1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "cpu.h"
21#include "disas/disas.h"
22#include "qemu/host-utils.h"
23#include "tcg-op.h"
24
25#include "helper.h"
26#define GEN_HELPER 1
27#include "helper.h"
28
29#undef ALPHA_DEBUG_DISAS
30#define CONFIG_SOFTFLOAT_INLINE
31
32#ifdef ALPHA_DEBUG_DISAS
33# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
34#else
35# define LOG_DISAS(...) do { } while (0)
36#endif
37
38typedef struct DisasContext DisasContext;
39struct DisasContext {
40 struct TranslationBlock *tb;
41 CPUAlphaState *env;
42 uint64_t pc;
43 int mem_idx;
44
45
46 int tb_rm;
47
48 int tb_ftz;
49};
50
51
52
53
54typedef enum {
55 NO_EXIT,
56
57
58 EXIT_GOTO_TB,
59
60
61
62
63 EXIT_PC_UPDATED,
64
65
66
67 EXIT_PC_STALE,
68
69
70
71 EXIT_NORETURN,
72} ExitStatus;
73
74
75static TCGv_ptr cpu_env;
76static TCGv cpu_ir[31];
77static TCGv cpu_fir[31];
78static TCGv cpu_pc;
79static TCGv cpu_lock_addr;
80static TCGv cpu_lock_st_addr;
81static TCGv cpu_lock_value;
82static TCGv cpu_unique;
83#ifndef CONFIG_USER_ONLY
84static TCGv cpu_sysval;
85static TCGv cpu_usp;
86#endif
87
88
89static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
90
91#include "exec/gen-icount.h"
92
93void alpha_translate_init(void)
94{
95 int i;
96 char *p;
97 static int done_init = 0;
98
99 if (done_init)
100 return;
101
102 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
103
104 p = cpu_reg_names;
105 for (i = 0; i < 31; i++) {
106 sprintf(p, "ir%d", i);
107 cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
108 offsetof(CPUAlphaState, ir[i]), p);
109 p += (i < 10) ? 4 : 5;
110
111 sprintf(p, "fir%d", i);
112 cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
113 offsetof(CPUAlphaState, fir[i]), p);
114 p += (i < 10) ? 5 : 6;
115 }
116
117 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
118 offsetof(CPUAlphaState, pc), "pc");
119
120 cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
121 offsetof(CPUAlphaState, lock_addr),
122 "lock_addr");
123 cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
124 offsetof(CPUAlphaState, lock_st_addr),
125 "lock_st_addr");
126 cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
127 offsetof(CPUAlphaState, lock_value),
128 "lock_value");
129
130 cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
131 offsetof(CPUAlphaState, unique), "unique");
132#ifndef CONFIG_USER_ONLY
133 cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
134 offsetof(CPUAlphaState, sysval), "sysval");
135 cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
136 offsetof(CPUAlphaState, usp), "usp");
137#endif
138
139
140#define GEN_HELPER 2
141#include "helper.h"
142
143 done_init = 1;
144}
145
146static void gen_excp_1(int exception, int error_code)
147{
148 TCGv_i32 tmp1, tmp2;
149
150 tmp1 = tcg_const_i32(exception);
151 tmp2 = tcg_const_i32(error_code);
152 gen_helper_excp(cpu_env, tmp1, tmp2);
153 tcg_temp_free_i32(tmp2);
154 tcg_temp_free_i32(tmp1);
155}
156
157static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
158{
159 tcg_gen_movi_i64(cpu_pc, ctx->pc);
160 gen_excp_1(exception, error_code);
161 return EXIT_NORETURN;
162}
163
164static inline ExitStatus gen_invalid(DisasContext *ctx)
165{
166 return gen_excp(ctx, EXCP_OPCDEC, 0);
167}
168
169static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
170{
171 TCGv tmp = tcg_temp_new();
172 TCGv_i32 tmp32 = tcg_temp_new_i32();
173 tcg_gen_qemu_ld32u(tmp, t1, flags);
174 tcg_gen_trunc_i64_i32(tmp32, tmp);
175 gen_helper_memory_to_f(t0, tmp32);
176 tcg_temp_free_i32(tmp32);
177 tcg_temp_free(tmp);
178}
179
180static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
181{
182 TCGv tmp = tcg_temp_new();
183 tcg_gen_qemu_ld64(tmp, t1, flags);
184 gen_helper_memory_to_g(t0, tmp);
185 tcg_temp_free(tmp);
186}
187
188static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
189{
190 TCGv tmp = tcg_temp_new();
191 TCGv_i32 tmp32 = tcg_temp_new_i32();
192 tcg_gen_qemu_ld32u(tmp, t1, flags);
193 tcg_gen_trunc_i64_i32(tmp32, tmp);
194 gen_helper_memory_to_s(t0, tmp32);
195 tcg_temp_free_i32(tmp32);
196 tcg_temp_free(tmp);
197}
198
199static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
200{
201 tcg_gen_qemu_ld32s(t0, t1, flags);
202 tcg_gen_mov_i64(cpu_lock_addr, t1);
203 tcg_gen_mov_i64(cpu_lock_value, t0);
204}
205
206static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
207{
208 tcg_gen_qemu_ld64(t0, t1, flags);
209 tcg_gen_mov_i64(cpu_lock_addr, t1);
210 tcg_gen_mov_i64(cpu_lock_value, t0);
211}
212
213static inline void gen_load_mem(DisasContext *ctx,
214 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
215 int flags),
216 int ra, int rb, int32_t disp16, int fp,
217 int clear)
218{
219 TCGv addr, va;
220
221
222
223
224 if (unlikely(ra == 31)) {
225 return;
226 }
227
228 addr = tcg_temp_new();
229 if (rb != 31) {
230 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
231 if (clear) {
232 tcg_gen_andi_i64(addr, addr, ~0x7);
233 }
234 } else {
235 if (clear) {
236 disp16 &= ~0x7;
237 }
238 tcg_gen_movi_i64(addr, disp16);
239 }
240
241 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
242 tcg_gen_qemu_load(va, addr, ctx->mem_idx);
243
244 tcg_temp_free(addr);
245}
246
247static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
248{
249 TCGv_i32 tmp32 = tcg_temp_new_i32();
250 TCGv tmp = tcg_temp_new();
251 gen_helper_f_to_memory(tmp32, t0);
252 tcg_gen_extu_i32_i64(tmp, tmp32);
253 tcg_gen_qemu_st32(tmp, t1, flags);
254 tcg_temp_free(tmp);
255 tcg_temp_free_i32(tmp32);
256}
257
258static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
259{
260 TCGv tmp = tcg_temp_new();
261 gen_helper_g_to_memory(tmp, t0);
262 tcg_gen_qemu_st64(tmp, t1, flags);
263 tcg_temp_free(tmp);
264}
265
266static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
267{
268 TCGv_i32 tmp32 = tcg_temp_new_i32();
269 TCGv tmp = tcg_temp_new();
270 gen_helper_s_to_memory(tmp32, t0);
271 tcg_gen_extu_i32_i64(tmp, tmp32);
272 tcg_gen_qemu_st32(tmp, t1, flags);
273 tcg_temp_free(tmp);
274 tcg_temp_free_i32(tmp32);
275}
276
277static inline void gen_store_mem(DisasContext *ctx,
278 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
279 int flags),
280 int ra, int rb, int32_t disp16, int fp,
281 int clear)
282{
283 TCGv addr, va;
284
285 addr = tcg_temp_new();
286 if (rb != 31) {
287 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
288 if (clear) {
289 tcg_gen_andi_i64(addr, addr, ~0x7);
290 }
291 } else {
292 if (clear) {
293 disp16 &= ~0x7;
294 }
295 tcg_gen_movi_i64(addr, disp16);
296 }
297
298 if (ra == 31) {
299 va = tcg_const_i64(0);
300 } else {
301 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
302 }
303 tcg_gen_qemu_store(va, addr, ctx->mem_idx);
304
305 tcg_temp_free(addr);
306 if (ra == 31) {
307 tcg_temp_free(va);
308 }
309}
310
311static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
312 int32_t disp16, int quad)
313{
314 TCGv addr;
315
316 if (ra == 31) {
317
318
319 return NO_EXIT;
320 }
321
322#if defined(CONFIG_USER_ONLY)
323 addr = cpu_lock_st_addr;
324#else
325 addr = tcg_temp_local_new();
326#endif
327
328 if (rb != 31) {
329 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
330 } else {
331 tcg_gen_movi_i64(addr, disp16);
332 }
333
334#if defined(CONFIG_USER_ONLY)
335
336
337
338 return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
339#else
340
341
342 {
343 int lab_fail, lab_done;
344 TCGv val;
345
346 lab_fail = gen_new_label();
347 lab_done = gen_new_label();
348 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
349
350 val = tcg_temp_new();
351 if (quad) {
352 tcg_gen_qemu_ld64(val, addr, ctx->mem_idx);
353 } else {
354 tcg_gen_qemu_ld32s(val, addr, ctx->mem_idx);
355 }
356 tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
357
358 if (quad) {
359 tcg_gen_qemu_st64(cpu_ir[ra], addr, ctx->mem_idx);
360 } else {
361 tcg_gen_qemu_st32(cpu_ir[ra], addr, ctx->mem_idx);
362 }
363 tcg_gen_movi_i64(cpu_ir[ra], 1);
364 tcg_gen_br(lab_done);
365
366 gen_set_label(lab_fail);
367 tcg_gen_movi_i64(cpu_ir[ra], 0);
368
369 gen_set_label(lab_done);
370 tcg_gen_movi_i64(cpu_lock_addr, -1);
371
372 tcg_temp_free(addr);
373 return NO_EXIT;
374 }
375#endif
376}
377
378static int use_goto_tb(DisasContext *ctx, uint64_t dest)
379{
380
381
382 return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
383 && !ctx->env->singlestep_enabled
384 && !(ctx->tb->cflags & CF_LAST_IO));
385}
386
387static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
388{
389 uint64_t dest = ctx->pc + (disp << 2);
390
391 if (ra != 31) {
392 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
393 }
394
395
396 if (disp == 0) {
397 return 0;
398 } else if (use_goto_tb(ctx, dest)) {
399 tcg_gen_goto_tb(0);
400 tcg_gen_movi_i64(cpu_pc, dest);
401 tcg_gen_exit_tb((tcg_target_long)ctx->tb);
402 return EXIT_GOTO_TB;
403 } else {
404 tcg_gen_movi_i64(cpu_pc, dest);
405 return EXIT_PC_UPDATED;
406 }
407}
408
409static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
410 TCGv cmp, int32_t disp)
411{
412 uint64_t dest = ctx->pc + (disp << 2);
413 int lab_true = gen_new_label();
414
415 if (use_goto_tb(ctx, dest)) {
416 tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
417
418 tcg_gen_goto_tb(0);
419 tcg_gen_movi_i64(cpu_pc, ctx->pc);
420 tcg_gen_exit_tb((tcg_target_long)ctx->tb);
421
422 gen_set_label(lab_true);
423 tcg_gen_goto_tb(1);
424 tcg_gen_movi_i64(cpu_pc, dest);
425 tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1);
426
427 return EXIT_GOTO_TB;
428 } else {
429 TCGv_i64 z = tcg_const_i64(0);
430 TCGv_i64 d = tcg_const_i64(dest);
431 TCGv_i64 p = tcg_const_i64(ctx->pc);
432
433 tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
434
435 tcg_temp_free_i64(z);
436 tcg_temp_free_i64(d);
437 tcg_temp_free_i64(p);
438 return EXIT_PC_UPDATED;
439 }
440}
441
442static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
443 int32_t disp, int mask)
444{
445 TCGv cmp_tmp;
446
447 if (unlikely(ra == 31)) {
448 cmp_tmp = tcg_const_i64(0);
449 } else {
450 cmp_tmp = tcg_temp_new();
451 if (mask) {
452 tcg_gen_andi_i64(cmp_tmp, cpu_ir[ra], 1);
453 } else {
454 tcg_gen_mov_i64(cmp_tmp, cpu_ir[ra]);
455 }
456 }
457
458 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
459}
460
461
462
463static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
464{
465 uint64_t mzero = 1ull << 63;
466
467 switch (cond) {
468 case TCG_COND_LE:
469 case TCG_COND_GT:
470
471 tcg_gen_mov_i64(dest, src);
472 break;
473
474 case TCG_COND_EQ:
475 case TCG_COND_NE:
476
477 tcg_gen_andi_i64(dest, src, mzero - 1);
478 break;
479
480 case TCG_COND_GE:
481 case TCG_COND_LT:
482
483 tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
484 tcg_gen_neg_i64(dest, dest);
485 tcg_gen_and_i64(dest, dest, src);
486 break;
487
488 default:
489 abort();
490 }
491}
492
493static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
494 int32_t disp)
495{
496 TCGv cmp_tmp;
497
498 if (unlikely(ra == 31)) {
499
500
501 return gen_bcond(ctx, cond, ra, disp, 0);
502 }
503
504 cmp_tmp = tcg_temp_new();
505 gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
506 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
507}
508
509static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
510 int islit, uint8_t lit, int mask)
511{
512 TCGv_i64 c1, z, v1;
513
514 if (unlikely(rc == 31)) {
515 return;
516 }
517
518 if (ra == 31) {
519
520 c1 = tcg_const_i64(0);
521 } else if (mask) {
522 c1 = tcg_const_i64(1);
523 tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
524 } else {
525 c1 = cpu_ir[ra];
526 }
527 if (islit) {
528 v1 = tcg_const_i64(lit);
529 } else {
530 v1 = cpu_ir[rb];
531 }
532 z = tcg_const_i64(0);
533
534 tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
535
536 tcg_temp_free_i64(z);
537 if (ra == 31 || mask) {
538 tcg_temp_free_i64(c1);
539 }
540 if (islit) {
541 tcg_temp_free_i64(v1);
542 }
543}
544
545static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
546{
547 TCGv_i64 c1, z, v1;
548
549 if (unlikely(rc == 31)) {
550 return;
551 }
552
553 c1 = tcg_temp_new_i64();
554 if (unlikely(ra == 31)) {
555 tcg_gen_movi_i64(c1, 0);
556 } else {
557 gen_fold_mzero(cond, c1, cpu_fir[ra]);
558 }
559 if (rb == 31) {
560 v1 = tcg_const_i64(0);
561 } else {
562 v1 = cpu_fir[rb];
563 }
564 z = tcg_const_i64(0);
565
566 tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
567
568 tcg_temp_free_i64(z);
569 tcg_temp_free_i64(c1);
570 if (rb == 31) {
571 tcg_temp_free_i64(v1);
572 }
573}
574
575#define QUAL_RM_N 0x080
576#define QUAL_RM_C 0x000
577#define QUAL_RM_M 0x040
578#define QUAL_RM_D 0x0c0
579#define QUAL_RM_MASK 0x0c0
580
581#define QUAL_U 0x100
582#define QUAL_V 0x100
583#define QUAL_S 0x400
584#define QUAL_I 0x200
585
586static void gen_qual_roundmode(DisasContext *ctx, int fn11)
587{
588 TCGv_i32 tmp;
589
590 fn11 &= QUAL_RM_MASK;
591 if (fn11 == ctx->tb_rm) {
592 return;
593 }
594 ctx->tb_rm = fn11;
595
596 tmp = tcg_temp_new_i32();
597 switch (fn11) {
598 case QUAL_RM_N:
599 tcg_gen_movi_i32(tmp, float_round_nearest_even);
600 break;
601 case QUAL_RM_C:
602 tcg_gen_movi_i32(tmp, float_round_to_zero);
603 break;
604 case QUAL_RM_M:
605 tcg_gen_movi_i32(tmp, float_round_down);
606 break;
607 case QUAL_RM_D:
608 tcg_gen_ld8u_i32(tmp, cpu_env,
609 offsetof(CPUAlphaState, fpcr_dyn_round));
610 break;
611 }
612
613#if defined(CONFIG_SOFTFLOAT_INLINE)
614
615
616
617 tcg_gen_st8_i32(tmp, cpu_env,
618 offsetof(CPUAlphaState, fp_status.float_rounding_mode));
619#else
620 gen_helper_setroundmode(tmp);
621#endif
622
623 tcg_temp_free_i32(tmp);
624}
625
626static void gen_qual_flushzero(DisasContext *ctx, int fn11)
627{
628 TCGv_i32 tmp;
629
630 fn11 &= QUAL_U;
631 if (fn11 == ctx->tb_ftz) {
632 return;
633 }
634 ctx->tb_ftz = fn11;
635
636 tmp = tcg_temp_new_i32();
637 if (fn11) {
638
639 tcg_gen_ld8u_i32(tmp, cpu_env,
640 offsetof(CPUAlphaState, fpcr_flush_to_zero));
641 } else {
642
643 tcg_gen_movi_i32(tmp, 1);
644 }
645
646#if defined(CONFIG_SOFTFLOAT_INLINE)
647 tcg_gen_st8_i32(tmp, cpu_env,
648 offsetof(CPUAlphaState, fp_status.flush_to_zero));
649#else
650 gen_helper_setflushzero(tmp);
651#endif
652
653 tcg_temp_free_i32(tmp);
654}
655
656static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
657{
658 TCGv val;
659 if (reg == 31) {
660 val = tcg_const_i64(0);
661 } else {
662 if ((fn11 & QUAL_S) == 0) {
663 if (is_cmp) {
664 gen_helper_ieee_input_cmp(cpu_env, cpu_fir[reg]);
665 } else {
666 gen_helper_ieee_input(cpu_env, cpu_fir[reg]);
667 }
668 }
669 val = tcg_temp_new();
670 tcg_gen_mov_i64(val, cpu_fir[reg]);
671 }
672 return val;
673}
674
675static void gen_fp_exc_clear(void)
676{
677#if defined(CONFIG_SOFTFLOAT_INLINE)
678 TCGv_i32 zero = tcg_const_i32(0);
679 tcg_gen_st8_i32(zero, cpu_env,
680 offsetof(CPUAlphaState, fp_status.float_exception_flags));
681 tcg_temp_free_i32(zero);
682#else
683 gen_helper_fp_exc_clear(cpu_env);
684#endif
685}
686
687static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
688{
689
690
691
692
693
694 TCGv_i32 exc = tcg_temp_new_i32();
695 TCGv_i32 reg;
696
697#if defined(CONFIG_SOFTFLOAT_INLINE)
698 tcg_gen_ld8u_i32(exc, cpu_env,
699 offsetof(CPUAlphaState, fp_status.float_exception_flags));
700#else
701 gen_helper_fp_exc_get(exc, cpu_env);
702#endif
703
704 if (ignore) {
705 tcg_gen_andi_i32(exc, exc, ~ignore);
706 }
707
708
709
710
711
712
713 reg = tcg_const_i32(rc + 32);
714
715 if (fn11 & QUAL_S) {
716 gen_helper_fp_exc_raise_s(cpu_env, exc, reg);
717 } else {
718 gen_helper_fp_exc_raise(cpu_env, exc, reg);
719 }
720
721 tcg_temp_free_i32(reg);
722 tcg_temp_free_i32(exc);
723}
724
725static inline void gen_fp_exc_raise(int rc, int fn11)
726{
727 gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
728}
729
730static void gen_fcvtlq(int rb, int rc)
731{
732 if (unlikely(rc == 31)) {
733 return;
734 }
735 if (unlikely(rb == 31)) {
736 tcg_gen_movi_i64(cpu_fir[rc], 0);
737 } else {
738 TCGv tmp = tcg_temp_new();
739
740
741
742 tcg_gen_sari_i64(tmp, cpu_fir[rb], 32);
743 tcg_gen_shri_i64(cpu_fir[rc], cpu_fir[rb], 29);
744 tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
745 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rc], 0x3fffffff);
746 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
747
748 tcg_temp_free(tmp);
749 }
750}
751
752static void gen_fcvtql(int rb, int rc)
753{
754 if (unlikely(rc == 31)) {
755 return;
756 }
757 if (unlikely(rb == 31)) {
758 tcg_gen_movi_i64(cpu_fir[rc], 0);
759 } else {
760 TCGv tmp = tcg_temp_new();
761
762 tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
763 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
764 tcg_gen_shli_i64(tmp, tmp, 32);
765 tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
766 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
767
768 tcg_temp_free(tmp);
769 }
770}
771
772static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
773{
774 if (rb != 31) {
775 int lab = gen_new_label();
776 TCGv tmp = tcg_temp_new();
777
778 tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
779 tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
780 gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
781
782 gen_set_label(lab);
783 }
784 gen_fcvtql(rb, rc);
785}
786
787#define FARITH2(name) \
788 static inline void glue(gen_f, name)(int rb, int rc) \
789 { \
790 if (unlikely(rc == 31)) { \
791 return; \
792 } \
793 if (rb != 31) { \
794 gen_helper_ ## name(cpu_fir[rc], cpu_env, cpu_fir[rb]); \
795 } else { \
796 TCGv tmp = tcg_const_i64(0); \
797 gen_helper_ ## name(cpu_fir[rc], cpu_env, tmp); \
798 tcg_temp_free(tmp); \
799 } \
800 }
801
802
803FARITH2(sqrtf)
804FARITH2(sqrtg)
805FARITH2(cvtgf)
806FARITH2(cvtgq)
807FARITH2(cvtqf)
808FARITH2(cvtqg)
809
810static void gen_ieee_arith2(DisasContext *ctx,
811 void (*helper)(TCGv, TCGv_ptr, TCGv),
812 int rb, int rc, int fn11)
813{
814 TCGv vb;
815
816
817
818 if (unlikely(rc == 31)) {
819 return;
820 }
821
822 gen_qual_roundmode(ctx, fn11);
823 gen_qual_flushzero(ctx, fn11);
824 gen_fp_exc_clear();
825
826 vb = gen_ieee_input(rb, fn11, 0);
827 helper(cpu_fir[rc], cpu_env, vb);
828 tcg_temp_free(vb);
829
830 gen_fp_exc_raise(rc, fn11);
831}
832
833#define IEEE_ARITH2(name) \
834static inline void glue(gen_f, name)(DisasContext *ctx, \
835 int rb, int rc, int fn11) \
836{ \
837 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \
838}
839IEEE_ARITH2(sqrts)
840IEEE_ARITH2(sqrtt)
841IEEE_ARITH2(cvtst)
842IEEE_ARITH2(cvtts)
843
844static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
845{
846 TCGv vb;
847 int ignore = 0;
848
849
850
851 if (unlikely(rc == 31)) {
852 return;
853 }
854
855
856 gen_fp_exc_clear();
857 vb = gen_ieee_input(rb, fn11, 0);
858
859
860
861 switch (fn11) {
862 case QUAL_RM_C:
863 gen_helper_cvttq_c(cpu_fir[rc], cpu_env, vb);
864 break;
865 case QUAL_V | QUAL_RM_C:
866 case QUAL_S | QUAL_V | QUAL_RM_C:
867 ignore = float_flag_inexact;
868
869 case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
870 gen_helper_cvttq_svic(cpu_fir[rc], cpu_env, vb);
871 break;
872 default:
873 gen_qual_roundmode(ctx, fn11);
874 gen_helper_cvttq(cpu_fir[rc], cpu_env, vb);
875 ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
876 ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
877 break;
878 }
879 tcg_temp_free(vb);
880
881 gen_fp_exc_raise_ignore(rc, fn11, ignore);
882}
883
884static void gen_ieee_intcvt(DisasContext *ctx,
885 void (*helper)(TCGv, TCGv_ptr, TCGv),
886 int rb, int rc, int fn11)
887{
888 TCGv vb;
889
890
891
892 if (unlikely(rc == 31)) {
893 return;
894 }
895
896 gen_qual_roundmode(ctx, fn11);
897
898 if (rb == 31) {
899 vb = tcg_const_i64(0);
900 } else {
901 vb = cpu_fir[rb];
902 }
903
904
905
906
907 if (fn11 & QUAL_I) {
908 gen_fp_exc_clear();
909 helper(cpu_fir[rc], cpu_env, vb);
910 gen_fp_exc_raise(rc, fn11);
911 } else {
912 helper(cpu_fir[rc], cpu_env, vb);
913 }
914
915 if (rb == 31) {
916 tcg_temp_free(vb);
917 }
918}
919
920#define IEEE_INTCVT(name) \
921static inline void glue(gen_f, name)(DisasContext *ctx, \
922 int rb, int rc, int fn11) \
923{ \
924 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \
925}
926IEEE_INTCVT(cvtqs)
927IEEE_INTCVT(cvtqt)
928
929static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask)
930{
931 TCGv va, vb, vmask;
932 int za = 0, zb = 0;
933
934 if (unlikely(rc == 31)) {
935 return;
936 }
937
938 vmask = tcg_const_i64(mask);
939
940 TCGV_UNUSED_I64(va);
941 if (ra == 31) {
942 if (inv_a) {
943 va = vmask;
944 } else {
945 za = 1;
946 }
947 } else {
948 va = tcg_temp_new_i64();
949 tcg_gen_mov_i64(va, cpu_fir[ra]);
950 if (inv_a) {
951 tcg_gen_andc_i64(va, vmask, va);
952 } else {
953 tcg_gen_and_i64(va, va, vmask);
954 }
955 }
956
957 TCGV_UNUSED_I64(vb);
958 if (rb == 31) {
959 zb = 1;
960 } else {
961 vb = tcg_temp_new_i64();
962 tcg_gen_andc_i64(vb, cpu_fir[rb], vmask);
963 }
964
965 switch (za << 1 | zb) {
966 case 0 | 0:
967 tcg_gen_or_i64(cpu_fir[rc], va, vb);
968 break;
969 case 0 | 1:
970 tcg_gen_mov_i64(cpu_fir[rc], va);
971 break;
972 case 2 | 0:
973 tcg_gen_mov_i64(cpu_fir[rc], vb);
974 break;
975 case 2 | 1:
976 tcg_gen_movi_i64(cpu_fir[rc], 0);
977 break;
978 }
979
980 tcg_temp_free(vmask);
981 if (ra != 31) {
982 tcg_temp_free(va);
983 }
984 if (rb != 31) {
985 tcg_temp_free(vb);
986 }
987}
988
989static inline void gen_fcpys(int ra, int rb, int rc)
990{
991 gen_cpys_internal(ra, rb, rc, 0, 0x8000000000000000ULL);
992}
993
994static inline void gen_fcpysn(int ra, int rb, int rc)
995{
996 gen_cpys_internal(ra, rb, rc, 1, 0x8000000000000000ULL);
997}
998
999static inline void gen_fcpyse(int ra, int rb, int rc)
1000{
1001 gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
1002}
1003
1004#define FARITH3(name) \
1005 static inline void glue(gen_f, name)(int ra, int rb, int rc) \
1006 { \
1007 TCGv va, vb; \
1008 \
1009 if (unlikely(rc == 31)) { \
1010 return; \
1011 } \
1012 if (ra == 31) { \
1013 va = tcg_const_i64(0); \
1014 } else { \
1015 va = cpu_fir[ra]; \
1016 } \
1017 if (rb == 31) { \
1018 vb = tcg_const_i64(0); \
1019 } else { \
1020 vb = cpu_fir[rb]; \
1021 } \
1022 \
1023 gen_helper_ ## name(cpu_fir[rc], cpu_env, va, vb); \
1024 \
1025 if (ra == 31) { \
1026 tcg_temp_free(va); \
1027 } \
1028 if (rb == 31) { \
1029 tcg_temp_free(vb); \
1030 } \
1031 }
1032
1033
1034FARITH3(addf)
1035FARITH3(subf)
1036FARITH3(mulf)
1037FARITH3(divf)
1038FARITH3(addg)
1039FARITH3(subg)
1040FARITH3(mulg)
1041FARITH3(divg)
1042FARITH3(cmpgeq)
1043FARITH3(cmpglt)
1044FARITH3(cmpgle)
1045
1046static void gen_ieee_arith3(DisasContext *ctx,
1047 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
1048 int ra, int rb, int rc, int fn11)
1049{
1050 TCGv va, vb;
1051
1052
1053
1054 if (unlikely(rc == 31)) {
1055 return;
1056 }
1057
1058 gen_qual_roundmode(ctx, fn11);
1059 gen_qual_flushzero(ctx, fn11);
1060 gen_fp_exc_clear();
1061
1062 va = gen_ieee_input(ra, fn11, 0);
1063 vb = gen_ieee_input(rb, fn11, 0);
1064 helper(cpu_fir[rc], cpu_env, va, vb);
1065 tcg_temp_free(va);
1066 tcg_temp_free(vb);
1067
1068 gen_fp_exc_raise(rc, fn11);
1069}
1070
1071#define IEEE_ARITH3(name) \
1072static inline void glue(gen_f, name)(DisasContext *ctx, \
1073 int ra, int rb, int rc, int fn11) \
1074{ \
1075 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1076}
1077IEEE_ARITH3(adds)
1078IEEE_ARITH3(subs)
1079IEEE_ARITH3(muls)
1080IEEE_ARITH3(divs)
1081IEEE_ARITH3(addt)
1082IEEE_ARITH3(subt)
1083IEEE_ARITH3(mult)
1084IEEE_ARITH3(divt)
1085
1086static void gen_ieee_compare(DisasContext *ctx,
1087 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
1088 int ra, int rb, int rc, int fn11)
1089{
1090 TCGv va, vb;
1091
1092
1093
1094 if (unlikely(rc == 31)) {
1095 return;
1096 }
1097
1098 gen_fp_exc_clear();
1099
1100 va = gen_ieee_input(ra, fn11, 1);
1101 vb = gen_ieee_input(rb, fn11, 1);
1102 helper(cpu_fir[rc], cpu_env, va, vb);
1103 tcg_temp_free(va);
1104 tcg_temp_free(vb);
1105
1106 gen_fp_exc_raise(rc, fn11);
1107}
1108
1109#define IEEE_CMP3(name) \
1110static inline void glue(gen_f, name)(DisasContext *ctx, \
1111 int ra, int rb, int rc, int fn11) \
1112{ \
1113 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1114}
1115IEEE_CMP3(cmptun)
1116IEEE_CMP3(cmpteq)
1117IEEE_CMP3(cmptlt)
1118IEEE_CMP3(cmptle)
1119
1120static inline uint64_t zapnot_mask(uint8_t lit)
1121{
1122 uint64_t mask = 0;
1123 int i;
1124
1125 for (i = 0; i < 8; ++i) {
1126 if ((lit >> i) & 1)
1127 mask |= 0xffull << (i * 8);
1128 }
1129 return mask;
1130}
1131
1132
1133
1134
1135static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
1136{
1137 switch (lit) {
1138 case 0x00:
1139 tcg_gen_movi_i64(dest, 0);
1140 break;
1141 case 0x01:
1142 tcg_gen_ext8u_i64(dest, src);
1143 break;
1144 case 0x03:
1145 tcg_gen_ext16u_i64(dest, src);
1146 break;
1147 case 0x0f:
1148 tcg_gen_ext32u_i64(dest, src);
1149 break;
1150 case 0xff:
1151 tcg_gen_mov_i64(dest, src);
1152 break;
1153 default:
1154 tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
1155 break;
1156 }
1157}
1158
1159static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
1160{
1161 if (unlikely(rc == 31))
1162 return;
1163 else if (unlikely(ra == 31))
1164 tcg_gen_movi_i64(cpu_ir[rc], 0);
1165 else if (islit)
1166 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
1167 else
1168 gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1169}
1170
1171static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
1172{
1173 if (unlikely(rc == 31))
1174 return;
1175 else if (unlikely(ra == 31))
1176 tcg_gen_movi_i64(cpu_ir[rc], 0);
1177 else if (islit)
1178 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
1179 else
1180 gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1181}
1182
1183
1184
1185static void gen_ext_h(int ra, int rb, int rc, int islit,
1186 uint8_t lit, uint8_t byte_mask)
1187{
1188 if (unlikely(rc == 31))
1189 return;
1190 else if (unlikely(ra == 31))
1191 tcg_gen_movi_i64(cpu_ir[rc], 0);
1192 else {
1193 if (islit) {
1194 lit = (64 - (lit & 7) * 8) & 0x3f;
1195 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1196 } else {
1197 TCGv tmp1 = tcg_temp_new();
1198 tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
1199 tcg_gen_shli_i64(tmp1, tmp1, 3);
1200 tcg_gen_neg_i64(tmp1, tmp1);
1201 tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1202 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
1203 tcg_temp_free(tmp1);
1204 }
1205 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1206 }
1207}
1208
1209
1210static void gen_ext_l(int ra, int rb, int rc, int islit,
1211 uint8_t lit, uint8_t byte_mask)
1212{
1213 if (unlikely(rc == 31))
1214 return;
1215 else if (unlikely(ra == 31))
1216 tcg_gen_movi_i64(cpu_ir[rc], 0);
1217 else {
1218 if (islit) {
1219 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
1220 } else {
1221 TCGv tmp = tcg_temp_new();
1222 tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
1223 tcg_gen_shli_i64(tmp, tmp, 3);
1224 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
1225 tcg_temp_free(tmp);
1226 }
1227 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1228 }
1229}
1230
1231
1232static void gen_ins_h(int ra, int rb, int rc, int islit,
1233 uint8_t lit, uint8_t byte_mask)
1234{
1235 if (unlikely(rc == 31))
1236 return;
1237 else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
1238 tcg_gen_movi_i64(cpu_ir[rc], 0);
1239 else {
1240 TCGv tmp = tcg_temp_new();
1241
1242
1243
1244
1245
1246 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1247
1248 if (islit) {
1249
1250 tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
1251 } else {
1252 TCGv shift = tcg_temp_new();
1253
1254
1255
1256
1257
1258
1259
1260 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1261 tcg_gen_shli_i64(shift, shift, 3);
1262 tcg_gen_not_i64(shift, shift);
1263 tcg_gen_andi_i64(shift, shift, 0x3f);
1264
1265 tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
1266 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
1267 tcg_temp_free(shift);
1268 }
1269 tcg_temp_free(tmp);
1270 }
1271}
1272
1273
1274static void gen_ins_l(int ra, int rb, int rc, int islit,
1275 uint8_t lit, uint8_t byte_mask)
1276{
1277 if (unlikely(rc == 31))
1278 return;
1279 else if (unlikely(ra == 31))
1280 tcg_gen_movi_i64(cpu_ir[rc], 0);
1281 else {
1282 TCGv tmp = tcg_temp_new();
1283
1284
1285
1286
1287
1288 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1289
1290 if (islit) {
1291 tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
1292 } else {
1293 TCGv shift = tcg_temp_new();
1294 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1295 tcg_gen_shli_i64(shift, shift, 3);
1296 tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
1297 tcg_temp_free(shift);
1298 }
1299 tcg_temp_free(tmp);
1300 }
1301}
1302
1303
1304static void gen_msk_h(int ra, int rb, int rc, int islit,
1305 uint8_t lit, uint8_t byte_mask)
1306{
1307 if (unlikely(rc == 31))
1308 return;
1309 else if (unlikely(ra == 31))
1310 tcg_gen_movi_i64(cpu_ir[rc], 0);
1311 else if (islit) {
1312 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
1313 } else {
1314 TCGv shift = tcg_temp_new();
1315 TCGv mask = tcg_temp_new();
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1327 tcg_gen_shli_i64(shift, shift, 3);
1328 tcg_gen_not_i64(shift, shift);
1329 tcg_gen_andi_i64(shift, shift, 0x3f);
1330 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1331 tcg_gen_shr_i64(mask, mask, shift);
1332 tcg_gen_shri_i64(mask, mask, 1);
1333
1334 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1335
1336 tcg_temp_free(mask);
1337 tcg_temp_free(shift);
1338 }
1339}
1340
1341
1342static void gen_msk_l(int ra, int rb, int rc, int islit,
1343 uint8_t lit, uint8_t byte_mask)
1344{
1345 if (unlikely(rc == 31))
1346 return;
1347 else if (unlikely(ra == 31))
1348 tcg_gen_movi_i64(cpu_ir[rc], 0);
1349 else if (islit) {
1350 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
1351 } else {
1352 TCGv shift = tcg_temp_new();
1353 TCGv mask = tcg_temp_new();
1354
1355 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1356 tcg_gen_shli_i64(shift, shift, 3);
1357 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1358 tcg_gen_shl_i64(mask, mask, shift);
1359
1360 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1361
1362 tcg_temp_free(mask);
1363 tcg_temp_free(shift);
1364 }
1365}
1366
1367
1368#define ARITH3(name) \
1369static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
1370 uint8_t lit) \
1371{ \
1372 if (unlikely(rc == 31)) \
1373 return; \
1374 \
1375 if (ra != 31) { \
1376 if (islit) { \
1377 TCGv tmp = tcg_const_i64(lit); \
1378 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
1379 tcg_temp_free(tmp); \
1380 } else \
1381 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1382 } else { \
1383 TCGv tmp1 = tcg_const_i64(0); \
1384 if (islit) { \
1385 TCGv tmp2 = tcg_const_i64(lit); \
1386 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
1387 tcg_temp_free(tmp2); \
1388 } else \
1389 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
1390 tcg_temp_free(tmp1); \
1391 } \
1392}
1393ARITH3(umulh)
1394ARITH3(cmpbge)
1395ARITH3(minub8)
1396ARITH3(minsb8)
1397ARITH3(minuw4)
1398ARITH3(minsw4)
1399ARITH3(maxub8)
1400ARITH3(maxsb8)
1401ARITH3(maxuw4)
1402ARITH3(maxsw4)
1403ARITH3(perr)
1404
1405
1406#define ARITH3_EX(name) \
1407 static inline void glue(gen_, name)(int ra, int rb, int rc, \
1408 int islit, uint8_t lit) \
1409 { \
1410 if (unlikely(rc == 31)) { \
1411 return; \
1412 } \
1413 if (ra != 31) { \
1414 if (islit) { \
1415 TCGv tmp = tcg_const_i64(lit); \
1416 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1417 cpu_ir[ra], tmp); \
1418 tcg_temp_free(tmp); \
1419 } else { \
1420 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1421 cpu_ir[ra], cpu_ir[rb]); \
1422 } \
1423 } else { \
1424 TCGv tmp1 = tcg_const_i64(0); \
1425 if (islit) { \
1426 TCGv tmp2 = tcg_const_i64(lit); \
1427 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2); \
1428 tcg_temp_free(tmp2); \
1429 } else { \
1430 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
1431 } \
1432 tcg_temp_free(tmp1); \
1433 } \
1434 }
1435ARITH3_EX(addlv)
1436ARITH3_EX(sublv)
1437ARITH3_EX(addqv)
1438ARITH3_EX(subqv)
1439ARITH3_EX(mullv)
1440ARITH3_EX(mulqv)
1441
1442#define MVIOP2(name) \
1443static inline void glue(gen_, name)(int rb, int rc) \
1444{ \
1445 if (unlikely(rc == 31)) \
1446 return; \
1447 if (unlikely(rb == 31)) \
1448 tcg_gen_movi_i64(cpu_ir[rc], 0); \
1449 else \
1450 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
1451}
1452MVIOP2(pklb)
1453MVIOP2(pkwb)
1454MVIOP2(unpkbl)
1455MVIOP2(unpkbw)
1456
1457static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
1458 int islit, uint8_t lit)
1459{
1460 TCGv va, vb;
1461
1462 if (unlikely(rc == 31)) {
1463 return;
1464 }
1465
1466 if (ra == 31) {
1467 va = tcg_const_i64(0);
1468 } else {
1469 va = cpu_ir[ra];
1470 }
1471 if (islit) {
1472 vb = tcg_const_i64(lit);
1473 } else {
1474 vb = cpu_ir[rb];
1475 }
1476
1477 tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
1478
1479 if (ra == 31) {
1480 tcg_temp_free(va);
1481 }
1482 if (islit) {
1483 tcg_temp_free(vb);
1484 }
1485}
1486
1487static void gen_rx(int ra, int set)
1488{
1489 TCGv_i32 tmp;
1490
1491 if (ra != 31) {
1492 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, offsetof(CPUAlphaState, intr_flag));
1493 }
1494
1495 tmp = tcg_const_i32(set);
1496 tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUAlphaState, intr_flag));
1497 tcg_temp_free_i32(tmp);
1498}
1499
1500static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1501{
1502
1503
1504
1505
1506 if (palcode >= 0x80 && palcode < 0xC0) {
1507 switch (palcode) {
1508 case 0x86:
1509
1510
1511 break;
1512 case 0x9E:
1513
1514 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
1515 break;
1516 case 0x9F:
1517
1518 tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
1519 break;
1520 default:
1521 return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
1522 }
1523 return NO_EXIT;
1524 }
1525
1526#ifndef CONFIG_USER_ONLY
1527
1528 if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1529 switch (palcode) {
1530 case 0x01:
1531
1532
1533 break;
1534 case 0x02:
1535
1536
1537 break;
1538 case 0x2D:
1539
1540 tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUAlphaState, vptptr));
1541 break;
1542 case 0x31:
1543
1544 tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
1545 break;
1546 case 0x32:
1547
1548 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
1549 break;
1550
1551 case 0x35: {
1552
1553 TCGv tmp;
1554
1555
1556
1557 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
1558
1559
1560 tmp = tcg_temp_new();
1561 tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
1562 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps));
1563 tcg_temp_free(tmp);
1564 break;
1565 }
1566
1567 case 0x36:
1568
1569 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
1570 break;
1571 case 0x38:
1572
1573 tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
1574 break;
1575 case 0x3A:
1576
1577 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
1578 break;
1579 case 0x3C:
1580
1581 tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
1582 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1583 break;
1584
1585 default:
1586 return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
1587 }
1588 return NO_EXIT;
1589 }
1590#endif
1591
1592 return gen_invalid(ctx);
1593}
1594
1595#ifndef CONFIG_USER_ONLY
1596
1597#define PR_BYTE 0x100000
1598#define PR_LONG 0x200000
1599
1600static int cpu_pr_data(int pr)
1601{
1602 switch (pr) {
1603 case 0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
1604 case 1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
1605 case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1606 case 3: return offsetof(CPUAlphaState, trap_arg0);
1607 case 4: return offsetof(CPUAlphaState, trap_arg1);
1608 case 5: return offsetof(CPUAlphaState, trap_arg2);
1609 case 6: return offsetof(CPUAlphaState, exc_addr);
1610 case 7: return offsetof(CPUAlphaState, palbr);
1611 case 8: return offsetof(CPUAlphaState, ptbr);
1612 case 9: return offsetof(CPUAlphaState, vptptr);
1613 case 10: return offsetof(CPUAlphaState, unique);
1614 case 11: return offsetof(CPUAlphaState, sysval);
1615 case 12: return offsetof(CPUAlphaState, usp);
1616
1617 case 32 ... 39:
1618 return offsetof(CPUAlphaState, shadow[pr - 32]);
1619 case 40 ... 63:
1620 return offsetof(CPUAlphaState, scratch[pr - 40]);
1621
1622 case 251:
1623 return offsetof(CPUAlphaState, alarm_expire);
1624 }
1625 return 0;
1626}
1627
1628static ExitStatus gen_mfpr(int ra, int regno)
1629{
1630 int data = cpu_pr_data(regno);
1631
1632
1633
1634 if (ra == 31) {
1635 return NO_EXIT;
1636 }
1637
1638 if (regno == 250) {
1639
1640 if (use_icount) {
1641 gen_io_start();
1642 gen_helper_get_time(cpu_ir[ra]);
1643 gen_io_end();
1644 return EXIT_PC_STALE;
1645 } else {
1646 gen_helper_get_time(cpu_ir[ra]);
1647 return NO_EXIT;
1648 }
1649 }
1650
1651
1652
1653 if (data == 0) {
1654 tcg_gen_movi_i64(cpu_ir[ra], 0);
1655 } else if (data & PR_BYTE) {
1656 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
1657 } else if (data & PR_LONG) {
1658 tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
1659 } else {
1660 tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
1661 }
1662 return NO_EXIT;
1663}
1664
1665static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
1666{
1667 TCGv tmp;
1668 int data;
1669
1670 if (rb == 31) {
1671 tmp = tcg_const_i64(0);
1672 } else {
1673 tmp = cpu_ir[rb];
1674 }
1675
1676 switch (regno) {
1677 case 255:
1678
1679 gen_helper_tbia(cpu_env);
1680 break;
1681
1682 case 254:
1683
1684 gen_helper_tbis(cpu_env, tmp);
1685 break;
1686
1687 case 253:
1688
1689 tmp = tcg_const_i64(1);
1690 tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUAlphaState, halted));
1691 return gen_excp(ctx, EXCP_HLT, 0);
1692
1693 case 252:
1694
1695 gen_helper_halt(tmp);
1696 return EXIT_PC_STALE;
1697
1698 case 251:
1699
1700 gen_helper_set_alarm(cpu_env, tmp);
1701 break;
1702
1703 default:
1704
1705
1706 data = cpu_pr_data(regno);
1707 if (data != 0) {
1708 if (data & PR_BYTE) {
1709 tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
1710 } else if (data & PR_LONG) {
1711 tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
1712 } else {
1713 tcg_gen_st_i64(tmp, cpu_env, data);
1714 }
1715 }
1716 break;
1717 }
1718
1719 if (rb == 31) {
1720 tcg_temp_free(tmp);
1721 }
1722
1723 return NO_EXIT;
1724}
1725#endif
1726
1727static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
1728{
1729 uint32_t palcode;
1730 int32_t disp21, disp16;
1731#ifndef CONFIG_USER_ONLY
1732 int32_t disp12;
1733#endif
1734 uint16_t fn11;
1735 uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit;
1736 uint8_t lit;
1737 ExitStatus ret;
1738
1739
1740 opc = insn >> 26;
1741 ra = (insn >> 21) & 0x1F;
1742 rb = (insn >> 16) & 0x1F;
1743 rc = insn & 0x1F;
1744 real_islit = islit = (insn >> 12) & 1;
1745 if (rb == 31 && !islit) {
1746 islit = 1;
1747 lit = 0;
1748 } else
1749 lit = (insn >> 13) & 0xFF;
1750 palcode = insn & 0x03FFFFFF;
1751 disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
1752 disp16 = (int16_t)(insn & 0x0000FFFF);
1753#ifndef CONFIG_USER_ONLY
1754 disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
1755#endif
1756 fn11 = (insn >> 5) & 0x000007FF;
1757 fpfn = fn11 & 0x3F;
1758 fn7 = (insn >> 5) & 0x0000007F;
1759 LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
1760 opc, ra, rb, rc, disp16);
1761
1762 ret = NO_EXIT;
1763 switch (opc) {
1764 case 0x00:
1765
1766 ret = gen_call_pal(ctx, palcode);
1767 break;
1768 case 0x01:
1769
1770 goto invalid_opc;
1771 case 0x02:
1772
1773 goto invalid_opc;
1774 case 0x03:
1775
1776 goto invalid_opc;
1777 case 0x04:
1778
1779 goto invalid_opc;
1780 case 0x05:
1781
1782 goto invalid_opc;
1783 case 0x06:
1784
1785 goto invalid_opc;
1786 case 0x07:
1787
1788 goto invalid_opc;
1789 case 0x08:
1790
1791 if (likely(ra != 31)) {
1792 if (rb != 31)
1793 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
1794 else
1795 tcg_gen_movi_i64(cpu_ir[ra], disp16);
1796 }
1797 break;
1798 case 0x09:
1799
1800 if (likely(ra != 31)) {
1801 if (rb != 31)
1802 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
1803 else
1804 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
1805 }
1806 break;
1807 case 0x0A:
1808
1809 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1810 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1811 break;
1812 }
1813 goto invalid_opc;
1814 case 0x0B:
1815
1816 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1817 break;
1818 case 0x0C:
1819
1820 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
1821 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1822 break;
1823 }
1824 goto invalid_opc;
1825 case 0x0D:
1826
1827 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1828 break;
1829 case 0x0E:
1830
1831 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1832 break;
1833 case 0x0F:
1834
1835 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1836 break;
1837 case 0x10:
1838 switch (fn7) {
1839 case 0x00:
1840
1841 if (likely(rc != 31)) {
1842 if (ra != 31) {
1843 if (islit) {
1844 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1845 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1846 } else {
1847 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1848 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1849 }
1850 } else {
1851 if (islit)
1852 tcg_gen_movi_i64(cpu_ir[rc], lit);
1853 else
1854 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1855 }
1856 }
1857 break;
1858 case 0x02:
1859
1860 if (likely(rc != 31)) {
1861 if (ra != 31) {
1862 TCGv tmp = tcg_temp_new();
1863 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1864 if (islit)
1865 tcg_gen_addi_i64(tmp, tmp, lit);
1866 else
1867 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1868 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1869 tcg_temp_free(tmp);
1870 } else {
1871 if (islit)
1872 tcg_gen_movi_i64(cpu_ir[rc], lit);
1873 else
1874 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1875 }
1876 }
1877 break;
1878 case 0x09:
1879
1880 if (likely(rc != 31)) {
1881 if (ra != 31) {
1882 if (islit)
1883 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1884 else
1885 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1886 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1887 } else {
1888 if (islit)
1889 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1890 else {
1891 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1892 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1893 }
1894 }
1895 break;
1896 case 0x0B:
1897
1898 if (likely(rc != 31)) {
1899 if (ra != 31) {
1900 TCGv tmp = tcg_temp_new();
1901 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1902 if (islit)
1903 tcg_gen_subi_i64(tmp, tmp, lit);
1904 else
1905 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1906 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1907 tcg_temp_free(tmp);
1908 } else {
1909 if (islit)
1910 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1911 else {
1912 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1913 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1914 }
1915 }
1916 }
1917 break;
1918 case 0x0F:
1919
1920 gen_cmpbge(ra, rb, rc, islit, lit);
1921 break;
1922 case 0x12:
1923
1924 if (likely(rc != 31)) {
1925 if (ra != 31) {
1926 TCGv tmp = tcg_temp_new();
1927 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1928 if (islit)
1929 tcg_gen_addi_i64(tmp, tmp, lit);
1930 else
1931 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1932 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1933 tcg_temp_free(tmp);
1934 } else {
1935 if (islit)
1936 tcg_gen_movi_i64(cpu_ir[rc], lit);
1937 else
1938 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
1939 }
1940 }
1941 break;
1942 case 0x1B:
1943
1944 if (likely(rc != 31)) {
1945 if (ra != 31) {
1946 TCGv tmp = tcg_temp_new();
1947 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1948 if (islit)
1949 tcg_gen_subi_i64(tmp, tmp, lit);
1950 else
1951 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1952 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1953 tcg_temp_free(tmp);
1954 } else {
1955 if (islit)
1956 tcg_gen_movi_i64(cpu_ir[rc], -lit);
1957 else
1958 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1959 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1960 }
1961 }
1962 }
1963 break;
1964 case 0x1D:
1965
1966 gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1967 break;
1968 case 0x20:
1969
1970 if (likely(rc != 31)) {
1971 if (ra != 31) {
1972 if (islit)
1973 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1974 else
1975 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1976 } else {
1977 if (islit)
1978 tcg_gen_movi_i64(cpu_ir[rc], lit);
1979 else
1980 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1981 }
1982 }
1983 break;
1984 case 0x22:
1985
1986 if (likely(rc != 31)) {
1987 if (ra != 31) {
1988 TCGv tmp = tcg_temp_new();
1989 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1990 if (islit)
1991 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1992 else
1993 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1994 tcg_temp_free(tmp);
1995 } else {
1996 if (islit)
1997 tcg_gen_movi_i64(cpu_ir[rc], lit);
1998 else
1999 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2000 }
2001 }
2002 break;
2003 case 0x29:
2004
2005 if (likely(rc != 31)) {
2006 if (ra != 31) {
2007 if (islit)
2008 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2009 else
2010 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2011 } else {
2012 if (islit)
2013 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2014 else
2015 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2016 }
2017 }
2018 break;
2019 case 0x2B:
2020
2021 if (likely(rc != 31)) {
2022 if (ra != 31) {
2023 TCGv tmp = tcg_temp_new();
2024 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
2025 if (islit)
2026 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
2027 else
2028 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2029 tcg_temp_free(tmp);
2030 } else {
2031 if (islit)
2032 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2033 else
2034 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2035 }
2036 }
2037 break;
2038 case 0x2D:
2039
2040 gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
2041 break;
2042 case 0x32:
2043
2044 if (likely(rc != 31)) {
2045 if (ra != 31) {
2046 TCGv tmp = tcg_temp_new();
2047 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
2048 if (islit)
2049 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
2050 else
2051 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2052 tcg_temp_free(tmp);
2053 } else {
2054 if (islit)
2055 tcg_gen_movi_i64(cpu_ir[rc], lit);
2056 else
2057 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2058 }
2059 }
2060 break;
2061 case 0x3B:
2062
2063 if (likely(rc != 31)) {
2064 if (ra != 31) {
2065 TCGv tmp = tcg_temp_new();
2066 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
2067 if (islit)
2068 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
2069 else
2070 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
2071 tcg_temp_free(tmp);
2072 } else {
2073 if (islit)
2074 tcg_gen_movi_i64(cpu_ir[rc], -lit);
2075 else
2076 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
2077 }
2078 }
2079 break;
2080 case 0x3D:
2081
2082 gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
2083 break;
2084 case 0x40:
2085
2086 gen_addlv(ra, rb, rc, islit, lit);
2087 break;
2088 case 0x49:
2089
2090 gen_sublv(ra, rb, rc, islit, lit);
2091 break;
2092 case 0x4D:
2093
2094 gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
2095 break;
2096 case 0x60:
2097
2098 gen_addqv(ra, rb, rc, islit, lit);
2099 break;
2100 case 0x69:
2101
2102 gen_subqv(ra, rb, rc, islit, lit);
2103 break;
2104 case 0x6D:
2105
2106 gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
2107 break;
2108 default:
2109 goto invalid_opc;
2110 }
2111 break;
2112 case 0x11:
2113 switch (fn7) {
2114 case 0x00:
2115
2116 if (likely(rc != 31)) {
2117 if (ra == 31)
2118 tcg_gen_movi_i64(cpu_ir[rc], 0);
2119 else if (islit)
2120 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
2121 else
2122 tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2123 }
2124 break;
2125 case 0x08:
2126
2127 if (likely(rc != 31)) {
2128 if (ra != 31) {
2129 if (islit)
2130 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2131 else
2132 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2133 } else
2134 tcg_gen_movi_i64(cpu_ir[rc], 0);
2135 }
2136 break;
2137 case 0x14:
2138
2139 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
2140 break;
2141 case 0x16:
2142
2143 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
2144 break;
2145 case 0x20:
2146
2147 if (likely(rc != 31)) {
2148 if (ra != 31) {
2149 if (islit)
2150 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2151 else
2152 tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2153 } else {
2154 if (islit)
2155 tcg_gen_movi_i64(cpu_ir[rc], lit);
2156 else
2157 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2158 }
2159 }
2160 break;
2161 case 0x24:
2162
2163 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
2164 break;
2165 case 0x26:
2166
2167 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
2168 break;
2169 case 0x28:
2170
2171 if (likely(rc != 31)) {
2172 if (ra != 31) {
2173 if (islit)
2174 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2175 else
2176 tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2177 } else {
2178 if (islit)
2179 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2180 else
2181 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2182 }
2183 }
2184 break;
2185 case 0x40:
2186
2187 if (likely(rc != 31)) {
2188 if (ra != 31) {
2189 if (islit)
2190 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
2191 else
2192 tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2193 } else {
2194 if (islit)
2195 tcg_gen_movi_i64(cpu_ir[rc], lit);
2196 else
2197 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
2198 }
2199 }
2200 break;
2201 case 0x44:
2202
2203 gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
2204 break;
2205 case 0x46:
2206
2207 gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
2208 break;
2209 case 0x48:
2210
2211 if (likely(rc != 31)) {
2212 if (ra != 31) {
2213 if (islit)
2214 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
2215 else
2216 tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2217 } else {
2218 if (islit)
2219 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
2220 else
2221 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
2222 }
2223 }
2224 break;
2225 case 0x61:
2226
2227 if (likely(rc != 31)) {
2228 uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
2229
2230 if (islit) {
2231 tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
2232 } else {
2233 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
2234 }
2235 }
2236 break;
2237 case 0x64:
2238
2239 gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
2240 break;
2241 case 0x66:
2242
2243 gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
2244 break;
2245 case 0x6C:
2246
2247 if (rc != 31)
2248 tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
2249 break;
2250 default:
2251 goto invalid_opc;
2252 }
2253 break;
2254 case 0x12:
2255 switch (fn7) {
2256 case 0x02:
2257
2258 gen_msk_l(ra, rb, rc, islit, lit, 0x01);
2259 break;
2260 case 0x06:
2261
2262 gen_ext_l(ra, rb, rc, islit, lit, 0x01);
2263 break;
2264 case 0x0B:
2265
2266 gen_ins_l(ra, rb, rc, islit, lit, 0x01);
2267 break;
2268 case 0x12:
2269
2270 gen_msk_l(ra, rb, rc, islit, lit, 0x03);
2271 break;
2272 case 0x16:
2273
2274 gen_ext_l(ra, rb, rc, islit, lit, 0x03);
2275 break;
2276 case 0x1B:
2277
2278 gen_ins_l(ra, rb, rc, islit, lit, 0x03);
2279 break;
2280 case 0x22:
2281
2282 gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
2283 break;
2284 case 0x26:
2285
2286 gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
2287 break;
2288 case 0x2B:
2289
2290 gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
2291 break;
2292 case 0x30:
2293
2294 gen_zap(ra, rb, rc, islit, lit);
2295 break;
2296 case 0x31:
2297
2298 gen_zapnot(ra, rb, rc, islit, lit);
2299 break;
2300 case 0x32:
2301
2302 gen_msk_l(ra, rb, rc, islit, lit, 0xff);
2303 break;
2304 case 0x34:
2305
2306 if (likely(rc != 31)) {
2307 if (ra != 31) {
2308 if (islit)
2309 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2310 else {
2311 TCGv shift = tcg_temp_new();
2312 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2313 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
2314 tcg_temp_free(shift);
2315 }
2316 } else
2317 tcg_gen_movi_i64(cpu_ir[rc], 0);
2318 }
2319 break;
2320 case 0x36:
2321
2322 gen_ext_l(ra, rb, rc, islit, lit, 0xff);
2323 break;
2324 case 0x39:
2325
2326 if (likely(rc != 31)) {
2327 if (ra != 31) {
2328 if (islit)
2329 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2330 else {
2331 TCGv shift = tcg_temp_new();
2332 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2333 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
2334 tcg_temp_free(shift);
2335 }
2336 } else
2337 tcg_gen_movi_i64(cpu_ir[rc], 0);
2338 }
2339 break;
2340 case 0x3B:
2341
2342 gen_ins_l(ra, rb, rc, islit, lit, 0xff);
2343 break;
2344 case 0x3C:
2345
2346 if (likely(rc != 31)) {
2347 if (ra != 31) {
2348 if (islit)
2349 tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
2350 else {
2351 TCGv shift = tcg_temp_new();
2352 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2353 tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
2354 tcg_temp_free(shift);
2355 }
2356 } else
2357 tcg_gen_movi_i64(cpu_ir[rc], 0);
2358 }
2359 break;
2360 case 0x52:
2361
2362 gen_msk_h(ra, rb, rc, islit, lit, 0x03);
2363 break;
2364 case 0x57:
2365
2366 gen_ins_h(ra, rb, rc, islit, lit, 0x03);
2367 break;
2368 case 0x5A:
2369
2370 gen_ext_h(ra, rb, rc, islit, lit, 0x03);
2371 break;
2372 case 0x62:
2373
2374 gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
2375 break;
2376 case 0x67:
2377
2378 gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
2379 break;
2380 case 0x6A:
2381
2382 gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
2383 break;
2384 case 0x72:
2385
2386 gen_msk_h(ra, rb, rc, islit, lit, 0xff);
2387 break;
2388 case 0x77:
2389
2390 gen_ins_h(ra, rb, rc, islit, lit, 0xff);
2391 break;
2392 case 0x7A:
2393
2394 gen_ext_h(ra, rb, rc, islit, lit, 0xff);
2395 break;
2396 default:
2397 goto invalid_opc;
2398 }
2399 break;
2400 case 0x13:
2401 switch (fn7) {
2402 case 0x00:
2403
2404 if (likely(rc != 31)) {
2405 if (ra == 31)
2406 tcg_gen_movi_i64(cpu_ir[rc], 0);
2407 else {
2408 if (islit)
2409 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2410 else
2411 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2412 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2413 }
2414 }
2415 break;
2416 case 0x20:
2417
2418 if (likely(rc != 31)) {
2419 if (ra == 31)
2420 tcg_gen_movi_i64(cpu_ir[rc], 0);
2421 else if (islit)
2422 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
2423 else
2424 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2425 }
2426 break;
2427 case 0x30:
2428
2429 gen_umulh(ra, rb, rc, islit, lit);
2430 break;
2431 case 0x40:
2432
2433 gen_mullv(ra, rb, rc, islit, lit);
2434 break;
2435 case 0x60:
2436
2437 gen_mulqv(ra, rb, rc, islit, lit);
2438 break;
2439 default:
2440 goto invalid_opc;
2441 }
2442 break;
2443 case 0x14:
2444 switch (fpfn) {
2445 case 0x04:
2446
2447 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2448 goto invalid_opc;
2449 }
2450 if (likely(rc != 31)) {
2451 if (ra != 31) {
2452 TCGv_i32 tmp = tcg_temp_new_i32();
2453 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2454 gen_helper_memory_to_s(cpu_fir[rc], tmp);
2455 tcg_temp_free_i32(tmp);
2456 } else
2457 tcg_gen_movi_i64(cpu_fir[rc], 0);
2458 }
2459 break;
2460 case 0x0A:
2461
2462 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2463 gen_fsqrtf(rb, rc);
2464 break;
2465 }
2466 goto invalid_opc;
2467 case 0x0B:
2468
2469 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2470 gen_fsqrts(ctx, rb, rc, fn11);
2471 break;
2472 }
2473 goto invalid_opc;
2474 case 0x14:
2475
2476 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2477 goto invalid_opc;
2478 }
2479 if (likely(rc != 31)) {
2480 if (ra != 31) {
2481 TCGv_i32 tmp = tcg_temp_new_i32();
2482 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
2483 gen_helper_memory_to_f(cpu_fir[rc], tmp);
2484 tcg_temp_free_i32(tmp);
2485 } else
2486 tcg_gen_movi_i64(cpu_fir[rc], 0);
2487 }
2488 break;
2489 case 0x24:
2490
2491 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
2492 goto invalid_opc;
2493 }
2494 if (likely(rc != 31)) {
2495 if (ra != 31)
2496 tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
2497 else
2498 tcg_gen_movi_i64(cpu_fir[rc], 0);
2499 }
2500 break;
2501 case 0x2A:
2502
2503 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2504 gen_fsqrtg(rb, rc);
2505 break;
2506 }
2507 goto invalid_opc;
2508 case 0x02B:
2509
2510 if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {
2511 gen_fsqrtt(ctx, rb, rc, fn11);
2512 break;
2513 }
2514 goto invalid_opc;
2515 default:
2516 goto invalid_opc;
2517 }
2518 break;
2519 case 0x15:
2520
2521
2522 switch (fpfn) {
2523 case 0x00:
2524
2525 gen_faddf(ra, rb, rc);
2526 break;
2527 case 0x01:
2528
2529 gen_fsubf(ra, rb, rc);
2530 break;
2531 case 0x02:
2532
2533 gen_fmulf(ra, rb, rc);
2534 break;
2535 case 0x03:
2536
2537 gen_fdivf(ra, rb, rc);
2538 break;
2539 case 0x1E:
2540
2541#if 0
2542 gen_fcvtdg(rb, rc);
2543#else
2544 goto invalid_opc;
2545#endif
2546 break;
2547 case 0x20:
2548
2549 gen_faddg(ra, rb, rc);
2550 break;
2551 case 0x21:
2552
2553 gen_fsubg(ra, rb, rc);
2554 break;
2555 case 0x22:
2556
2557 gen_fmulg(ra, rb, rc);
2558 break;
2559 case 0x23:
2560
2561 gen_fdivg(ra, rb, rc);
2562 break;
2563 case 0x25:
2564
2565 gen_fcmpgeq(ra, rb, rc);
2566 break;
2567 case 0x26:
2568
2569 gen_fcmpglt(ra, rb, rc);
2570 break;
2571 case 0x27:
2572
2573 gen_fcmpgle(ra, rb, rc);
2574 break;
2575 case 0x2C:
2576
2577 gen_fcvtgf(rb, rc);
2578 break;
2579 case 0x2D:
2580
2581#if 0
2582 gen_fcvtgd(rb, rc);
2583#else
2584 goto invalid_opc;
2585#endif
2586 break;
2587 case 0x2F:
2588
2589 gen_fcvtgq(rb, rc);
2590 break;
2591 case 0x3C:
2592
2593 gen_fcvtqf(rb, rc);
2594 break;
2595 case 0x3E:
2596
2597 gen_fcvtqg(rb, rc);
2598 break;
2599 default:
2600 goto invalid_opc;
2601 }
2602 break;
2603 case 0x16:
2604
2605 switch (fpfn) {
2606 case 0x00:
2607
2608 gen_fadds(ctx, ra, rb, rc, fn11);
2609 break;
2610 case 0x01:
2611
2612 gen_fsubs(ctx, ra, rb, rc, fn11);
2613 break;
2614 case 0x02:
2615
2616 gen_fmuls(ctx, ra, rb, rc, fn11);
2617 break;
2618 case 0x03:
2619
2620 gen_fdivs(ctx, ra, rb, rc, fn11);
2621 break;
2622 case 0x20:
2623
2624 gen_faddt(ctx, ra, rb, rc, fn11);
2625 break;
2626 case 0x21:
2627
2628 gen_fsubt(ctx, ra, rb, rc, fn11);
2629 break;
2630 case 0x22:
2631
2632 gen_fmult(ctx, ra, rb, rc, fn11);
2633 break;
2634 case 0x23:
2635
2636 gen_fdivt(ctx, ra, rb, rc, fn11);
2637 break;
2638 case 0x24:
2639
2640 gen_fcmptun(ctx, ra, rb, rc, fn11);
2641 break;
2642 case 0x25:
2643
2644 gen_fcmpteq(ctx, ra, rb, rc, fn11);
2645 break;
2646 case 0x26:
2647
2648 gen_fcmptlt(ctx, ra, rb, rc, fn11);
2649 break;
2650 case 0x27:
2651
2652 gen_fcmptle(ctx, ra, rb, rc, fn11);
2653 break;
2654 case 0x2C:
2655 if (fn11 == 0x2AC || fn11 == 0x6AC) {
2656
2657 gen_fcvtst(ctx, rb, rc, fn11);
2658 } else {
2659
2660 gen_fcvtts(ctx, rb, rc, fn11);
2661 }
2662 break;
2663 case 0x2F:
2664
2665 gen_fcvttq(ctx, rb, rc, fn11);
2666 break;
2667 case 0x3C:
2668
2669 gen_fcvtqs(ctx, rb, rc, fn11);
2670 break;
2671 case 0x3E:
2672
2673 gen_fcvtqt(ctx, rb, rc, fn11);
2674 break;
2675 default:
2676 goto invalid_opc;
2677 }
2678 break;
2679 case 0x17:
2680 switch (fn11) {
2681 case 0x010:
2682
2683 gen_fcvtlq(rb, rc);
2684 break;
2685 case 0x020:
2686 if (likely(rc != 31)) {
2687 if (ra == rb) {
2688
2689 if (ra == 31)
2690 tcg_gen_movi_i64(cpu_fir[rc], 0);
2691 else
2692 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
2693 } else {
2694
2695 gen_fcpys(ra, rb, rc);
2696 }
2697 }
2698 break;
2699 case 0x021:
2700
2701 gen_fcpysn(ra, rb, rc);
2702 break;
2703 case 0x022:
2704
2705 gen_fcpyse(ra, rb, rc);
2706 break;
2707 case 0x024:
2708
2709 if (likely(ra != 31))
2710 gen_helper_store_fpcr(cpu_env, cpu_fir[ra]);
2711 else {
2712 TCGv tmp = tcg_const_i64(0);
2713 gen_helper_store_fpcr(cpu_env, tmp);
2714 tcg_temp_free(tmp);
2715 }
2716 break;
2717 case 0x025:
2718
2719 if (likely(ra != 31))
2720 gen_helper_load_fpcr(cpu_fir[ra], cpu_env);
2721 break;
2722 case 0x02A:
2723
2724 gen_fcmov(TCG_COND_EQ, ra, rb, rc);
2725 break;
2726 case 0x02B:
2727
2728 gen_fcmov(TCG_COND_NE, ra, rb, rc);
2729 break;
2730 case 0x02C:
2731
2732 gen_fcmov(TCG_COND_LT, ra, rb, rc);
2733 break;
2734 case 0x02D:
2735
2736 gen_fcmov(TCG_COND_GE, ra, rb, rc);
2737 break;
2738 case 0x02E:
2739
2740 gen_fcmov(TCG_COND_LE, ra, rb, rc);
2741 break;
2742 case 0x02F:
2743
2744 gen_fcmov(TCG_COND_GT, ra, rb, rc);
2745 break;
2746 case 0x030:
2747
2748 gen_fcvtql(rb, rc);
2749 break;
2750 case 0x130:
2751
2752 case 0x530:
2753
2754
2755
2756
2757 gen_fcvtql_v(ctx, rb, rc);
2758 break;
2759 default:
2760 goto invalid_opc;
2761 }
2762 break;
2763 case 0x18:
2764 switch ((uint16_t)disp16) {
2765 case 0x0000:
2766
2767
2768 break;
2769 case 0x0400:
2770
2771
2772 break;
2773 case 0x4000:
2774
2775
2776 break;
2777 case 0x4400:
2778
2779
2780 break;
2781 case 0x8000:
2782
2783
2784 break;
2785 case 0xA000:
2786
2787
2788 break;
2789 case 0xC000:
2790
2791 if (ra != 31) {
2792 if (use_icount) {
2793 gen_io_start();
2794 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
2795 gen_io_end();
2796 ret = EXIT_PC_STALE;
2797 } else {
2798 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
2799 }
2800 }
2801 break;
2802 case 0xE000:
2803
2804 gen_rx(ra, 0);
2805 break;
2806 case 0xE800:
2807
2808 break;
2809 case 0xF000:
2810
2811 gen_rx(ra, 1);
2812 break;
2813 case 0xF800:
2814
2815
2816 break;
2817 default:
2818 goto invalid_opc;
2819 }
2820 break;
2821 case 0x19:
2822
2823#ifndef CONFIG_USER_ONLY
2824 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2825 return gen_mfpr(ra, insn & 0xffff);
2826 }
2827#endif
2828 goto invalid_opc;
2829 case 0x1A:
2830
2831
2832 if (rb != 31) {
2833 tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
2834 } else {
2835 tcg_gen_movi_i64(cpu_pc, 0);
2836 }
2837 if (ra != 31) {
2838 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2839 }
2840 ret = EXIT_PC_UPDATED;
2841 break;
2842 case 0x1B:
2843
2844#ifndef CONFIG_USER_ONLY
2845 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
2846 TCGv addr;
2847
2848 if (ra == 31) {
2849 break;
2850 }
2851
2852 addr = tcg_temp_new();
2853 if (rb != 31)
2854 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2855 else
2856 tcg_gen_movi_i64(addr, disp12);
2857 switch ((insn >> 12) & 0xF) {
2858 case 0x0:
2859
2860 gen_helper_ldl_phys(cpu_ir[ra], addr);
2861 break;
2862 case 0x1:
2863
2864 gen_helper_ldq_phys(cpu_ir[ra], addr);
2865 break;
2866 case 0x2:
2867
2868 gen_helper_ldl_l_phys(cpu_ir[ra], cpu_env, addr);
2869 break;
2870 case 0x3:
2871
2872 gen_helper_ldq_l_phys(cpu_ir[ra], cpu_env, addr);
2873 break;
2874 case 0x4:
2875
2876 goto invalid_opc;
2877 case 0x5:
2878
2879 goto invalid_opc;
2880 break;
2881 case 0x6:
2882
2883 goto invalid_opc;
2884 case 0x7:
2885
2886 goto invalid_opc;
2887 case 0x8:
2888
2889 goto invalid_opc;
2890 case 0x9:
2891
2892 goto invalid_opc;
2893 case 0xA:
2894
2895 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2896 break;
2897 case 0xB:
2898
2899 tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX);
2900 break;
2901 case 0xC:
2902
2903 goto invalid_opc;
2904 case 0xD:
2905
2906 goto invalid_opc;
2907 case 0xE:
2908
2909
2910 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX);
2911 break;
2912 case 0xF:
2913
2914
2915 tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX);
2916 break;
2917 }
2918 tcg_temp_free(addr);
2919 break;
2920 }
2921#endif
2922 goto invalid_opc;
2923 case 0x1C:
2924 switch (fn7) {
2925 case 0x00:
2926
2927 if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {
2928 goto invalid_opc;
2929 }
2930 if (likely(rc != 31)) {
2931 if (islit)
2932 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
2933 else
2934 tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
2935 }
2936 break;
2937 case 0x01:
2938
2939 if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
2940 if (likely(rc != 31)) {
2941 if (islit) {
2942 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
2943 } else {
2944 tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
2945 }
2946 }
2947 break;
2948 }
2949 goto invalid_opc;
2950 case 0x30:
2951
2952 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2953 if (likely(rc != 31)) {
2954 if (islit) {
2955 tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
2956 } else {
2957 gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
2958 }
2959 }
2960 break;
2961 }
2962 goto invalid_opc;
2963 case 0x31:
2964
2965 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2966 gen_perr(ra, rb, rc, islit, lit);
2967 break;
2968 }
2969 goto invalid_opc;
2970 case 0x32:
2971
2972 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2973 if (likely(rc != 31)) {
2974 if (islit) {
2975 tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
2976 } else {
2977 gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
2978 }
2979 }
2980 break;
2981 }
2982 goto invalid_opc;
2983 case 0x33:
2984
2985 if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {
2986 if (likely(rc != 31)) {
2987 if (islit) {
2988 tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
2989 } else {
2990 gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
2991 }
2992 }
2993 break;
2994 }
2995 goto invalid_opc;
2996 case 0x34:
2997
2998 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
2999 if (real_islit || ra != 31) {
3000 goto invalid_opc;
3001 }
3002 gen_unpkbw(rb, rc);
3003 break;
3004 }
3005 goto invalid_opc;
3006 case 0x35:
3007
3008 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3009 if (real_islit || ra != 31) {
3010 goto invalid_opc;
3011 }
3012 gen_unpkbl(rb, rc);
3013 break;
3014 }
3015 goto invalid_opc;
3016 case 0x36:
3017
3018 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3019 if (real_islit || ra != 31) {
3020 goto invalid_opc;
3021 }
3022 gen_pkwb(rb, rc);
3023 break;
3024 }
3025 goto invalid_opc;
3026 case 0x37:
3027
3028 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3029 if (real_islit || ra != 31) {
3030 goto invalid_opc;
3031 }
3032 gen_pklb(rb, rc);
3033 break;
3034 }
3035 goto invalid_opc;
3036 case 0x38:
3037
3038 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3039 gen_minsb8(ra, rb, rc, islit, lit);
3040 break;
3041 }
3042 goto invalid_opc;
3043 case 0x39:
3044
3045 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3046 gen_minsw4(ra, rb, rc, islit, lit);
3047 break;
3048 }
3049 goto invalid_opc;
3050 case 0x3A:
3051
3052 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3053 gen_minub8(ra, rb, rc, islit, lit);
3054 break;
3055 }
3056 goto invalid_opc;
3057 case 0x3B:
3058
3059 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3060 gen_minuw4(ra, rb, rc, islit, lit);
3061 break;
3062 }
3063 goto invalid_opc;
3064 case 0x3C:
3065
3066 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3067 gen_maxub8(ra, rb, rc, islit, lit);
3068 break;
3069 }
3070 goto invalid_opc;
3071 case 0x3D:
3072
3073 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3074 gen_maxuw4(ra, rb, rc, islit, lit);
3075 break;
3076 }
3077 goto invalid_opc;
3078 case 0x3E:
3079
3080 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3081 gen_maxsb8(ra, rb, rc, islit, lit);
3082 break;
3083 }
3084 goto invalid_opc;
3085 case 0x3F:
3086
3087 if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {
3088 gen_maxsw4(ra, rb, rc, islit, lit);
3089 break;
3090 }
3091 goto invalid_opc;
3092 case 0x70:
3093
3094 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3095 goto invalid_opc;
3096 }
3097 if (likely(rc != 31)) {
3098 if (ra != 31)
3099 tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
3100 else
3101 tcg_gen_movi_i64(cpu_ir[rc], 0);
3102 }
3103 break;
3104 case 0x78:
3105
3106 if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
3107 goto invalid_opc;
3108 }
3109 if (rc != 31) {
3110 TCGv_i32 tmp1 = tcg_temp_new_i32();
3111 if (ra != 31)
3112 gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
3113 else {
3114 TCGv tmp2 = tcg_const_i64(0);
3115 gen_helper_s_to_memory(tmp1, tmp2);
3116 tcg_temp_free(tmp2);
3117 }
3118 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
3119 tcg_temp_free_i32(tmp1);
3120 }
3121 break;
3122 default:
3123 goto invalid_opc;
3124 }
3125 break;
3126 case 0x1D:
3127
3128#ifndef CONFIG_USER_ONLY
3129 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3130 return gen_mtpr(ctx, rb, insn & 0xffff);
3131 }
3132#endif
3133 goto invalid_opc;
3134 case 0x1E:
3135
3136#ifndef CONFIG_USER_ONLY
3137 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3138 if (rb == 31) {
3139
3140
3141
3142 TCGv tmp = tcg_temp_new();
3143 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
3144 gen_helper_hw_ret(cpu_env, tmp);
3145 tcg_temp_free(tmp);
3146 } else {
3147 gen_helper_hw_ret(cpu_env, cpu_ir[rb]);
3148 }
3149 ret = EXIT_PC_UPDATED;
3150 break;
3151 }
3152#endif
3153 goto invalid_opc;
3154 case 0x1F:
3155
3156#ifndef CONFIG_USER_ONLY
3157 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
3158 TCGv addr, val;
3159 addr = tcg_temp_new();
3160 if (rb != 31)
3161 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
3162 else
3163 tcg_gen_movi_i64(addr, disp12);
3164 if (ra != 31)
3165 val = cpu_ir[ra];
3166 else {
3167 val = tcg_temp_new();
3168 tcg_gen_movi_i64(val, 0);
3169 }
3170 switch ((insn >> 12) & 0xF) {
3171 case 0x0:
3172
3173 gen_helper_stl_phys(addr, val);
3174 break;
3175 case 0x1:
3176
3177 gen_helper_stq_phys(addr, val);
3178 break;
3179 case 0x2:
3180
3181 gen_helper_stl_c_phys(val, cpu_env, addr, val);
3182 break;
3183 case 0x3:
3184
3185 gen_helper_stq_c_phys(val, cpu_env, addr, val);
3186 break;
3187 case 0x4:
3188
3189 goto invalid_opc;
3190 case 0x5:
3191
3192 goto invalid_opc;
3193 case 0x6:
3194
3195 goto invalid_opc;
3196 case 0x7:
3197
3198 goto invalid_opc;
3199 case 0x8:
3200
3201 goto invalid_opc;
3202 case 0x9:
3203
3204 goto invalid_opc;
3205 case 0xA:
3206
3207 goto invalid_opc;
3208 case 0xB:
3209
3210 goto invalid_opc;
3211 case 0xC:
3212
3213 goto invalid_opc;
3214 case 0xD:
3215
3216 goto invalid_opc;
3217 case 0xE:
3218
3219 goto invalid_opc;
3220 case 0xF:
3221
3222 goto invalid_opc;
3223 }
3224 if (ra == 31)
3225 tcg_temp_free(val);
3226 tcg_temp_free(addr);
3227 break;
3228 }
3229#endif
3230 goto invalid_opc;
3231 case 0x20:
3232
3233 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
3234 break;
3235 case 0x21:
3236
3237 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
3238 break;
3239 case 0x22:
3240
3241 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
3242 break;
3243 case 0x23:
3244
3245 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
3246 break;
3247 case 0x24:
3248
3249 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
3250 break;
3251 case 0x25:
3252
3253 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
3254 break;
3255 case 0x26:
3256
3257 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
3258 break;
3259 case 0x27:
3260
3261 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
3262 break;
3263 case 0x28:
3264
3265 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
3266 break;
3267 case 0x29:
3268
3269 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
3270 break;
3271 case 0x2A:
3272
3273 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
3274 break;
3275 case 0x2B:
3276
3277 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
3278 break;
3279 case 0x2C:
3280
3281 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
3282 break;
3283 case 0x2D:
3284
3285 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
3286 break;
3287 case 0x2E:
3288
3289 ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
3290 break;
3291 case 0x2F:
3292
3293 ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
3294 break;
3295 case 0x30:
3296
3297 ret = gen_bdirect(ctx, ra, disp21);
3298 break;
3299 case 0x31:
3300 ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
3301 break;
3302 case 0x32:
3303 ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
3304 break;
3305 case 0x33:
3306 ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
3307 break;
3308 case 0x34:
3309
3310 ret = gen_bdirect(ctx, ra, disp21);
3311 break;
3312 case 0x35:
3313 ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
3314 break;
3315 case 0x36:
3316 ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
3317 break;
3318 case 0x37:
3319 ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
3320 break;
3321 case 0x38:
3322
3323 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
3324 break;
3325 case 0x39:
3326
3327 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
3328 break;
3329 case 0x3A:
3330
3331 ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
3332 break;
3333 case 0x3B:
3334
3335 ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
3336 break;
3337 case 0x3C:
3338
3339 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
3340 break;
3341 case 0x3D:
3342
3343 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
3344 break;
3345 case 0x3E:
3346
3347 ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
3348 break;
3349 case 0x3F:
3350
3351 ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
3352 break;
3353 invalid_opc:
3354 ret = gen_invalid(ctx);
3355 break;
3356 }
3357
3358 return ret;
3359}
3360
3361static inline void gen_intermediate_code_internal(CPUAlphaState *env,
3362 TranslationBlock *tb,
3363 int search_pc)
3364{
3365 DisasContext ctx, *ctxp = &ctx;
3366 target_ulong pc_start;
3367 uint32_t insn;
3368 uint16_t *gen_opc_end;
3369 CPUBreakpoint *bp;
3370 int j, lj = -1;
3371 ExitStatus ret;
3372 int num_insns;
3373 int max_insns;
3374
3375 pc_start = tb->pc;
3376 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
3377
3378 ctx.tb = tb;
3379 ctx.env = env;
3380 ctx.pc = pc_start;
3381 ctx.mem_idx = cpu_mmu_index(env);
3382
3383
3384
3385
3386
3387
3388
3389 ctx.tb_rm = -1;
3390
3391 ctx.tb_ftz = -1;
3392
3393 num_insns = 0;
3394 max_insns = tb->cflags & CF_COUNT_MASK;
3395 if (max_insns == 0)
3396 max_insns = CF_COUNT_MASK;
3397
3398 gen_icount_start();
3399 do {
3400 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
3401 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
3402 if (bp->pc == ctx.pc) {
3403 gen_excp(&ctx, EXCP_DEBUG, 0);
3404 break;
3405 }
3406 }
3407 }
3408 if (search_pc) {
3409 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3410 if (lj < j) {
3411 lj++;
3412 while (lj < j)
3413 tcg_ctx.gen_opc_instr_start[lj++] = 0;
3414 }
3415 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
3416 tcg_ctx.gen_opc_instr_start[lj] = 1;
3417 tcg_ctx.gen_opc_icount[lj] = num_insns;
3418 }
3419 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3420 gen_io_start();
3421 insn = cpu_ldl_code(env, ctx.pc);
3422 num_insns++;
3423
3424 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3425 tcg_gen_debug_insn_start(ctx.pc);
3426 }
3427
3428 ctx.pc += 4;
3429 ret = translate_one(ctxp, insn);
3430
3431
3432
3433 if (ret == NO_EXIT
3434 && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
3435 || tcg_ctx.gen_opc_ptr >= gen_opc_end
3436 || num_insns >= max_insns
3437 || singlestep
3438 || env->singlestep_enabled)) {
3439 ret = EXIT_PC_STALE;
3440 }
3441 } while (ret == NO_EXIT);
3442
3443 if (tb->cflags & CF_LAST_IO) {
3444 gen_io_end();
3445 }
3446
3447 switch (ret) {
3448 case EXIT_GOTO_TB:
3449 case EXIT_NORETURN:
3450 break;
3451 case EXIT_PC_STALE:
3452 tcg_gen_movi_i64(cpu_pc, ctx.pc);
3453
3454 case EXIT_PC_UPDATED:
3455 if (env->singlestep_enabled) {
3456 gen_excp_1(EXCP_DEBUG, 0);
3457 } else {
3458 tcg_gen_exit_tb(0);
3459 }
3460 break;
3461 default:
3462 abort();
3463 }
3464
3465 gen_icount_end(tb, num_insns);
3466 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
3467 if (search_pc) {
3468 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
3469 lj++;
3470 while (lj <= j)
3471 tcg_ctx.gen_opc_instr_start[lj++] = 0;
3472 } else {
3473 tb->size = ctx.pc - pc_start;
3474 tb->icount = num_insns;
3475 }
3476
3477#ifdef DEBUG_DISAS
3478 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3479 qemu_log("IN: %s\n", lookup_symbol(pc_start));
3480 log_target_disas(env, pc_start, ctx.pc - pc_start, 1);
3481 qemu_log("\n");
3482 }
3483#endif
3484}
3485
3486void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb)
3487{
3488 gen_intermediate_code_internal(env, tb, 0);
3489}
3490
3491void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
3492{
3493 gen_intermediate_code_internal(env, tb, 1);
3494}
3495
3496void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
3497{
3498 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3499}
3500