target/mips: Add simple user-mode mips_cpu_do_interrupt()
[qemu/ar7.git] / target / tricore / translate.c
blob2a814263de62fe1ef32e74320f234b2ec8b3be77
1 /*
2 * TriCore emulation for qemu: main translation routines.
4 * Copyright (c) 2013-2014 Bastian Koppelmann C-Lab/University Paderborn
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg/tcg-op.h"
26 #include "exec/cpu_ldst.h"
27 #include "qemu/qemu-print.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
32 #include "tricore-opcodes.h"
33 #include "exec/translator.h"
34 #include "exec/log.h"
37 * TCG registers
39 static TCGv cpu_PC;
40 static TCGv cpu_PCXI;
41 static TCGv cpu_PSW;
42 static TCGv cpu_ICR;
43 /* GPR registers */
44 static TCGv cpu_gpr_a[16];
45 static TCGv cpu_gpr_d[16];
46 /* PSW Flag cache */
47 static TCGv cpu_PSW_C;
48 static TCGv cpu_PSW_V;
49 static TCGv cpu_PSW_SV;
50 static TCGv cpu_PSW_AV;
51 static TCGv cpu_PSW_SAV;
53 #include "exec/gen-icount.h"
55 static const char *regnames_a[] = {
56 "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
57 "a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
58 "a12" , "a13" , "a14" , "a15",
61 static const char *regnames_d[] = {
62 "d0" , "d1" , "d2" , "d3" , "d4" , "d5" ,
63 "d6" , "d7" , "d8" , "d9" , "d10" , "d11" ,
64 "d12" , "d13" , "d14" , "d15",
67 typedef struct DisasContext {
68 DisasContextBase base;
69 target_ulong pc_succ_insn;
70 uint32_t opcode;
71 /* Routine used to access memory */
72 int mem_idx;
73 uint32_t hflags, saved_hflags;
74 uint64_t features;
75 } DisasContext;
77 static int has_feature(DisasContext *ctx, int feature)
79 return (ctx->features & (1ULL << feature)) != 0;
82 enum {
83 MODE_LL = 0,
84 MODE_LU = 1,
85 MODE_UL = 2,
86 MODE_UU = 3,
89 void tricore_cpu_dump_state(CPUState *cs, FILE *f, int flags)
91 TriCoreCPU *cpu = TRICORE_CPU(cs);
92 CPUTriCoreState *env = &cpu->env;
93 uint32_t psw;
94 int i;
96 psw = psw_read(env);
98 qemu_fprintf(f, "PC: " TARGET_FMT_lx, env->PC);
99 qemu_fprintf(f, " PSW: " TARGET_FMT_lx, psw);
100 qemu_fprintf(f, " ICR: " TARGET_FMT_lx, env->ICR);
101 qemu_fprintf(f, "\nPCXI: " TARGET_FMT_lx, env->PCXI);
102 qemu_fprintf(f, " FCX: " TARGET_FMT_lx, env->FCX);
103 qemu_fprintf(f, " LCX: " TARGET_FMT_lx, env->LCX);
105 for (i = 0; i < 16; ++i) {
106 if ((i & 3) == 0) {
107 qemu_fprintf(f, "\nGPR A%02d:", i);
109 qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_a[i]);
111 for (i = 0; i < 16; ++i) {
112 if ((i & 3) == 0) {
113 qemu_fprintf(f, "\nGPR D%02d:", i);
115 qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_d[i]);
117 qemu_fprintf(f, "\n");
121 * Functions to generate micro-ops
124 /* Makros for generating helpers */
126 #define gen_helper_1arg(name, arg) do { \
127 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
128 gen_helper_##name(cpu_env, helper_tmp); \
129 tcg_temp_free_i32(helper_tmp); \
130 } while (0)
132 #define GEN_HELPER_LL(name, ret, arg0, arg1, n) do { \
133 TCGv arg00 = tcg_temp_new(); \
134 TCGv arg01 = tcg_temp_new(); \
135 TCGv arg11 = tcg_temp_new(); \
136 tcg_gen_sari_tl(arg00, arg0, 16); \
137 tcg_gen_ext16s_tl(arg01, arg0); \
138 tcg_gen_ext16s_tl(arg11, arg1); \
139 gen_helper_##name(ret, arg00, arg01, arg11, arg11, n); \
140 tcg_temp_free(arg00); \
141 tcg_temp_free(arg01); \
142 tcg_temp_free(arg11); \
143 } while (0)
145 #define GEN_HELPER_LU(name, ret, arg0, arg1, n) do { \
146 TCGv arg00 = tcg_temp_new(); \
147 TCGv arg01 = tcg_temp_new(); \
148 TCGv arg10 = tcg_temp_new(); \
149 TCGv arg11 = tcg_temp_new(); \
150 tcg_gen_sari_tl(arg00, arg0, 16); \
151 tcg_gen_ext16s_tl(arg01, arg0); \
152 tcg_gen_sari_tl(arg11, arg1, 16); \
153 tcg_gen_ext16s_tl(arg10, arg1); \
154 gen_helper_##name(ret, arg00, arg01, arg10, arg11, n); \
155 tcg_temp_free(arg00); \
156 tcg_temp_free(arg01); \
157 tcg_temp_free(arg10); \
158 tcg_temp_free(arg11); \
159 } while (0)
161 #define GEN_HELPER_UL(name, ret, arg0, arg1, n) do { \
162 TCGv arg00 = tcg_temp_new(); \
163 TCGv arg01 = tcg_temp_new(); \
164 TCGv arg10 = tcg_temp_new(); \
165 TCGv arg11 = tcg_temp_new(); \
166 tcg_gen_sari_tl(arg00, arg0, 16); \
167 tcg_gen_ext16s_tl(arg01, arg0); \
168 tcg_gen_sari_tl(arg10, arg1, 16); \
169 tcg_gen_ext16s_tl(arg11, arg1); \
170 gen_helper_##name(ret, arg00, arg01, arg10, arg11, n); \
171 tcg_temp_free(arg00); \
172 tcg_temp_free(arg01); \
173 tcg_temp_free(arg10); \
174 tcg_temp_free(arg11); \
175 } while (0)
177 #define GEN_HELPER_UU(name, ret, arg0, arg1, n) do { \
178 TCGv arg00 = tcg_temp_new(); \
179 TCGv arg01 = tcg_temp_new(); \
180 TCGv arg11 = tcg_temp_new(); \
181 tcg_gen_sari_tl(arg01, arg0, 16); \
182 tcg_gen_ext16s_tl(arg00, arg0); \
183 tcg_gen_sari_tl(arg11, arg1, 16); \
184 gen_helper_##name(ret, arg00, arg01, arg11, arg11, n); \
185 tcg_temp_free(arg00); \
186 tcg_temp_free(arg01); \
187 tcg_temp_free(arg11); \
188 } while (0)
190 #define GEN_HELPER_RRR(name, rl, rh, al1, ah1, arg2) do { \
191 TCGv_i64 ret = tcg_temp_new_i64(); \
192 TCGv_i64 arg1 = tcg_temp_new_i64(); \
194 tcg_gen_concat_i32_i64(arg1, al1, ah1); \
195 gen_helper_##name(ret, arg1, arg2); \
196 tcg_gen_extr_i64_i32(rl, rh, ret); \
198 tcg_temp_free_i64(ret); \
199 tcg_temp_free_i64(arg1); \
200 } while (0)
202 #define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do { \
203 TCGv_i64 ret = tcg_temp_new_i64(); \
205 gen_helper_##name(ret, cpu_env, arg1, arg2); \
206 tcg_gen_extr_i64_i32(rl, rh, ret); \
208 tcg_temp_free_i64(ret); \
209 } while (0)
211 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
212 #define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
213 ((offset & 0x0fffff) << 1))
215 /* For two 32-bit registers used a 64-bit register, the first
216 registernumber needs to be even. Otherwise we trap. */
217 static inline void generate_trap(DisasContext *ctx, int class, int tin);
218 #define CHECK_REG_PAIR(reg) do { \
219 if (reg & 0x1) { \
220 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_OPD); \
222 } while (0)
224 /* Functions for load/save to/from memory */
226 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
227 int16_t con, MemOp mop)
229 TCGv temp = tcg_temp_new();
230 tcg_gen_addi_tl(temp, r2, con);
231 tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
232 tcg_temp_free(temp);
235 static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
236 int16_t con, MemOp mop)
238 TCGv temp = tcg_temp_new();
239 tcg_gen_addi_tl(temp, r2, con);
240 tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
241 tcg_temp_free(temp);
244 static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
246 TCGv_i64 temp = tcg_temp_new_i64();
248 tcg_gen_concat_i32_i64(temp, rl, rh);
249 tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
251 tcg_temp_free_i64(temp);
254 static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
255 DisasContext *ctx)
257 TCGv temp = tcg_temp_new();
258 tcg_gen_addi_tl(temp, base, con);
259 gen_st_2regs_64(rh, rl, temp, ctx);
260 tcg_temp_free(temp);
263 static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
265 TCGv_i64 temp = tcg_temp_new_i64();
267 tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
268 /* write back to two 32 bit regs */
269 tcg_gen_extr_i64_i32(rl, rh, temp);
271 tcg_temp_free_i64(temp);
274 static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
275 DisasContext *ctx)
277 TCGv temp = tcg_temp_new();
278 tcg_gen_addi_tl(temp, base, con);
279 gen_ld_2regs_64(rh, rl, temp, ctx);
280 tcg_temp_free(temp);
283 static void gen_st_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
284 MemOp mop)
286 TCGv temp = tcg_temp_new();
287 tcg_gen_addi_tl(temp, r2, off);
288 tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
289 tcg_gen_mov_tl(r2, temp);
290 tcg_temp_free(temp);
293 static void gen_ld_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
294 MemOp mop)
296 TCGv temp = tcg_temp_new();
297 tcg_gen_addi_tl(temp, r2, off);
298 tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
299 tcg_gen_mov_tl(r2, temp);
300 tcg_temp_free(temp);
303 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
304 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
306 TCGv temp = tcg_temp_new();
307 TCGv temp2 = tcg_temp_new();
309 CHECK_REG_PAIR(ereg);
310 /* temp = (M(EA, word) */
311 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
312 /* temp = temp & ~E[a][63:32]) */
313 tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
314 /* temp2 = (E[a][31:0] & E[a][63:32]); */
315 tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
316 /* temp = temp | temp2; */
317 tcg_gen_or_tl(temp, temp, temp2);
318 /* M(EA, word) = temp; */
319 tcg_gen_qemu_st_tl(temp, ea, ctx->mem_idx, MO_LEUL);
321 tcg_temp_free(temp);
322 tcg_temp_free(temp2);
325 /* tmp = M(EA, word);
326 M(EA, word) = D[a];
327 D[a] = tmp[31:0];*/
328 static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
330 TCGv temp = tcg_temp_new();
332 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
333 tcg_gen_qemu_st_tl(cpu_gpr_d[reg], ea, ctx->mem_idx, MO_LEUL);
334 tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
336 tcg_temp_free(temp);
339 static void gen_cmpswap(DisasContext *ctx, int reg, TCGv ea)
341 TCGv temp = tcg_temp_new();
342 TCGv temp2 = tcg_temp_new();
343 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
344 tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp,
345 cpu_gpr_d[reg], temp);
346 tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
347 tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
349 tcg_temp_free(temp);
350 tcg_temp_free(temp2);
353 static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea)
355 TCGv temp = tcg_temp_new();
356 TCGv temp2 = tcg_temp_new();
357 TCGv temp3 = tcg_temp_new();
359 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
360 tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]);
361 tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]);
362 tcg_gen_or_tl(temp2, temp2, temp3);
363 tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
364 tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
366 tcg_temp_free(temp);
367 tcg_temp_free(temp2);
368 tcg_temp_free(temp3);
372 /* We generate loads and store to core special function register (csfr) through
373 the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
374 makros R, A and E, which allow read-only, all and endinit protected access.
375 These makros also specify in which ISA version the csfr was introduced. */
376 #define R(ADDRESS, REG, FEATURE) \
377 case ADDRESS: \
378 if (has_feature(ctx, FEATURE)) { \
379 tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
381 break;
382 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
383 #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
384 static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset)
386 /* since we're caching PSW make this a special case */
387 if (offset == 0xfe04) {
388 gen_helper_psw_read(ret, cpu_env);
389 } else {
390 switch (offset) {
391 #include "csfr.def"
395 #undef R
396 #undef A
397 #undef E
399 #define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
400 since no execption occurs */
401 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
402 case ADDRESS: \
403 if (has_feature(ctx, FEATURE)) { \
404 tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \
406 break;
407 /* Endinit protected registers
408 TODO: Since the endinit bit is in a register of a not yet implemented
409 watchdog device, we handle endinit protected registers like
410 all-access registers for now. */
411 #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
412 static inline void gen_mtcr(DisasContext *ctx, TCGv r1,
413 int32_t offset)
415 if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
416 /* since we're caching PSW make this a special case */
417 if (offset == 0xfe04) {
418 gen_helper_psw_write(cpu_env, r1);
419 } else {
420 switch (offset) {
421 #include "csfr.def"
424 } else {
425 /* generate privilege trap */
429 /* Functions for arithmetic instructions */
431 static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
433 TCGv t0 = tcg_temp_new_i32();
434 TCGv result = tcg_temp_new_i32();
435 /* Addition and set V/SV bits */
436 tcg_gen_add_tl(result, r1, r2);
437 /* calc V bit */
438 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
439 tcg_gen_xor_tl(t0, r1, r2);
440 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
441 /* Calc SV bit */
442 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
443 /* Calc AV/SAV bits */
444 tcg_gen_add_tl(cpu_PSW_AV, result, result);
445 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
446 /* calc SAV */
447 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
448 /* write back result */
449 tcg_gen_mov_tl(ret, result);
451 tcg_temp_free(result);
452 tcg_temp_free(t0);
455 static inline void
456 gen_add64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
458 TCGv temp = tcg_temp_new();
459 TCGv_i64 t0 = tcg_temp_new_i64();
460 TCGv_i64 t1 = tcg_temp_new_i64();
461 TCGv_i64 result = tcg_temp_new_i64();
463 tcg_gen_add_i64(result, r1, r2);
464 /* calc v bit */
465 tcg_gen_xor_i64(t1, result, r1);
466 tcg_gen_xor_i64(t0, r1, r2);
467 tcg_gen_andc_i64(t1, t1, t0);
468 tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
469 /* calc SV bit */
470 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
471 /* calc AV/SAV bits */
472 tcg_gen_extrh_i64_i32(temp, result);
473 tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
474 tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
475 /* calc SAV */
476 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
477 /* write back result */
478 tcg_gen_mov_i64(ret, result);
480 tcg_temp_free(temp);
481 tcg_temp_free_i64(result);
482 tcg_temp_free_i64(t0);
483 tcg_temp_free_i64(t1);
486 static inline void
487 gen_addsub64_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
488 TCGv r3, void(*op1)(TCGv, TCGv, TCGv),
489 void(*op2)(TCGv, TCGv, TCGv))
491 TCGv temp = tcg_temp_new();
492 TCGv temp2 = tcg_temp_new();
493 TCGv temp3 = tcg_temp_new();
494 TCGv temp4 = tcg_temp_new();
496 (*op1)(temp, r1_low, r2);
497 /* calc V0 bit */
498 tcg_gen_xor_tl(temp2, temp, r1_low);
499 tcg_gen_xor_tl(temp3, r1_low, r2);
500 if (op1 == tcg_gen_add_tl) {
501 tcg_gen_andc_tl(temp2, temp2, temp3);
502 } else {
503 tcg_gen_and_tl(temp2, temp2, temp3);
506 (*op2)(temp3, r1_high, r3);
507 /* calc V1 bit */
508 tcg_gen_xor_tl(cpu_PSW_V, temp3, r1_high);
509 tcg_gen_xor_tl(temp4, r1_high, r3);
510 if (op2 == tcg_gen_add_tl) {
511 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, temp4);
512 } else {
513 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp4);
515 /* combine V0/V1 bits */
516 tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp2);
517 /* calc sv bit */
518 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
519 /* write result */
520 tcg_gen_mov_tl(ret_low, temp);
521 tcg_gen_mov_tl(ret_high, temp3);
522 /* calc AV bit */
523 tcg_gen_add_tl(temp, ret_low, ret_low);
524 tcg_gen_xor_tl(temp, temp, ret_low);
525 tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
526 tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, ret_high);
527 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
528 /* calc SAV bit */
529 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
531 tcg_temp_free(temp);
532 tcg_temp_free(temp2);
533 tcg_temp_free(temp3);
534 tcg_temp_free(temp4);
537 /* ret = r2 + (r1 * r3); */
538 static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
540 TCGv_i64 t1 = tcg_temp_new_i64();
541 TCGv_i64 t2 = tcg_temp_new_i64();
542 TCGv_i64 t3 = tcg_temp_new_i64();
544 tcg_gen_ext_i32_i64(t1, r1);
545 tcg_gen_ext_i32_i64(t2, r2);
546 tcg_gen_ext_i32_i64(t3, r3);
548 tcg_gen_mul_i64(t1, t1, t3);
549 tcg_gen_add_i64(t1, t2, t1);
551 tcg_gen_extrl_i64_i32(ret, t1);
552 /* calc V
553 t1 > 0x7fffffff */
554 tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
555 /* t1 < -0x80000000 */
556 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
557 tcg_gen_or_i64(t2, t2, t3);
558 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
559 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
560 /* Calc SV bit */
561 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
562 /* Calc AV/SAV bits */
563 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
564 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
565 /* calc SAV */
566 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
568 tcg_temp_free_i64(t1);
569 tcg_temp_free_i64(t2);
570 tcg_temp_free_i64(t3);
573 static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
575 TCGv temp = tcg_const_i32(con);
576 gen_madd32_d(ret, r1, r2, temp);
577 tcg_temp_free(temp);
580 static inline void
581 gen_madd64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
582 TCGv r3)
584 TCGv t1 = tcg_temp_new();
585 TCGv t2 = tcg_temp_new();
586 TCGv t3 = tcg_temp_new();
587 TCGv t4 = tcg_temp_new();
589 tcg_gen_muls2_tl(t1, t2, r1, r3);
590 /* only the add can overflow */
591 tcg_gen_add2_tl(t3, t4, r2_low, r2_high, t1, t2);
592 /* calc V bit */
593 tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
594 tcg_gen_xor_tl(t1, r2_high, t2);
595 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t1);
596 /* Calc SV bit */
597 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
598 /* Calc AV/SAV bits */
599 tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
600 tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
601 /* calc SAV */
602 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
603 /* write back the result */
604 tcg_gen_mov_tl(ret_low, t3);
605 tcg_gen_mov_tl(ret_high, t4);
607 tcg_temp_free(t1);
608 tcg_temp_free(t2);
609 tcg_temp_free(t3);
610 tcg_temp_free(t4);
613 static inline void
614 gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
615 TCGv r3)
617 TCGv_i64 t1 = tcg_temp_new_i64();
618 TCGv_i64 t2 = tcg_temp_new_i64();
619 TCGv_i64 t3 = tcg_temp_new_i64();
621 tcg_gen_extu_i32_i64(t1, r1);
622 tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
623 tcg_gen_extu_i32_i64(t3, r3);
625 tcg_gen_mul_i64(t1, t1, t3);
626 tcg_gen_add_i64(t2, t2, t1);
627 /* write back result */
628 tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
629 /* only the add overflows, if t2 < t1
630 calc V bit */
631 tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
632 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
633 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
634 /* Calc SV bit */
635 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
636 /* Calc AV/SAV bits */
637 tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
638 tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
639 /* calc SAV */
640 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
642 tcg_temp_free_i64(t1);
643 tcg_temp_free_i64(t2);
644 tcg_temp_free_i64(t3);
647 static inline void
648 gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
649 int32_t con)
651 TCGv temp = tcg_const_i32(con);
652 gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
653 tcg_temp_free(temp);
656 static inline void
657 gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
658 int32_t con)
660 TCGv temp = tcg_const_i32(con);
661 gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
662 tcg_temp_free(temp);
665 static inline void
666 gen_madd_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
667 TCGv r3, uint32_t n, uint32_t mode)
669 TCGv temp = tcg_const_i32(n);
670 TCGv temp2 = tcg_temp_new();
671 TCGv_i64 temp64 = tcg_temp_new_i64();
672 switch (mode) {
673 case MODE_LL:
674 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
675 break;
676 case MODE_LU:
677 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
678 break;
679 case MODE_UL:
680 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
681 break;
682 case MODE_UU:
683 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
684 break;
686 tcg_gen_extr_i64_i32(temp, temp2, temp64);
687 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
688 tcg_gen_add_tl, tcg_gen_add_tl);
689 tcg_temp_free(temp);
690 tcg_temp_free(temp2);
691 tcg_temp_free_i64(temp64);
694 static inline void
695 gen_maddsu_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
696 TCGv r3, uint32_t n, uint32_t mode)
698 TCGv temp = tcg_const_i32(n);
699 TCGv temp2 = tcg_temp_new();
700 TCGv_i64 temp64 = tcg_temp_new_i64();
701 switch (mode) {
702 case MODE_LL:
703 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
704 break;
705 case MODE_LU:
706 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
707 break;
708 case MODE_UL:
709 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
710 break;
711 case MODE_UU:
712 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
713 break;
715 tcg_gen_extr_i64_i32(temp, temp2, temp64);
716 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
717 tcg_gen_sub_tl, tcg_gen_add_tl);
718 tcg_temp_free(temp);
719 tcg_temp_free(temp2);
720 tcg_temp_free_i64(temp64);
723 static inline void
724 gen_maddsum_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
725 TCGv r3, uint32_t n, uint32_t mode)
727 TCGv temp = tcg_const_i32(n);
728 TCGv_i64 temp64 = tcg_temp_new_i64();
729 TCGv_i64 temp64_2 = tcg_temp_new_i64();
730 TCGv_i64 temp64_3 = tcg_temp_new_i64();
731 switch (mode) {
732 case MODE_LL:
733 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
734 break;
735 case MODE_LU:
736 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
737 break;
738 case MODE_UL:
739 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
740 break;
741 case MODE_UU:
742 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
743 break;
745 tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
746 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
747 tcg_gen_ext32s_i64(temp64, temp64); /* low */
748 tcg_gen_sub_i64(temp64, temp64_2, temp64);
749 tcg_gen_shli_i64(temp64, temp64, 16);
751 gen_add64_d(temp64_2, temp64_3, temp64);
752 /* write back result */
753 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
755 tcg_temp_free(temp);
756 tcg_temp_free_i64(temp64);
757 tcg_temp_free_i64(temp64_2);
758 tcg_temp_free_i64(temp64_3);
761 static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2);
763 static inline void
764 gen_madds_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
765 TCGv r3, uint32_t n, uint32_t mode)
767 TCGv temp = tcg_const_i32(n);
768 TCGv temp2 = tcg_temp_new();
769 TCGv temp3 = tcg_temp_new();
770 TCGv_i64 temp64 = tcg_temp_new_i64();
772 switch (mode) {
773 case MODE_LL:
774 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
775 break;
776 case MODE_LU:
777 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
778 break;
779 case MODE_UL:
780 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
781 break;
782 case MODE_UU:
783 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
784 break;
786 tcg_gen_extr_i64_i32(temp, temp2, temp64);
787 gen_adds(ret_low, r1_low, temp);
788 tcg_gen_mov_tl(temp, cpu_PSW_V);
789 tcg_gen_mov_tl(temp3, cpu_PSW_AV);
790 gen_adds(ret_high, r1_high, temp2);
791 /* combine v bits */
792 tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
793 /* combine av bits */
794 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
796 tcg_temp_free(temp);
797 tcg_temp_free(temp2);
798 tcg_temp_free(temp3);
799 tcg_temp_free_i64(temp64);
803 static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2);
805 static inline void
806 gen_maddsus_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
807 TCGv r3, uint32_t n, uint32_t mode)
809 TCGv temp = tcg_const_i32(n);
810 TCGv temp2 = tcg_temp_new();
811 TCGv temp3 = tcg_temp_new();
812 TCGv_i64 temp64 = tcg_temp_new_i64();
814 switch (mode) {
815 case MODE_LL:
816 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
817 break;
818 case MODE_LU:
819 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
820 break;
821 case MODE_UL:
822 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
823 break;
824 case MODE_UU:
825 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
826 break;
828 tcg_gen_extr_i64_i32(temp, temp2, temp64);
829 gen_subs(ret_low, r1_low, temp);
830 tcg_gen_mov_tl(temp, cpu_PSW_V);
831 tcg_gen_mov_tl(temp3, cpu_PSW_AV);
832 gen_adds(ret_high, r1_high, temp2);
833 /* combine v bits */
834 tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
835 /* combine av bits */
836 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
838 tcg_temp_free(temp);
839 tcg_temp_free(temp2);
840 tcg_temp_free(temp3);
841 tcg_temp_free_i64(temp64);
845 static inline void
846 gen_maddsums_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
847 TCGv r3, uint32_t n, uint32_t mode)
849 TCGv temp = tcg_const_i32(n);
850 TCGv_i64 temp64 = tcg_temp_new_i64();
851 TCGv_i64 temp64_2 = tcg_temp_new_i64();
853 switch (mode) {
854 case MODE_LL:
855 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
856 break;
857 case MODE_LU:
858 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
859 break;
860 case MODE_UL:
861 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
862 break;
863 case MODE_UU:
864 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
865 break;
867 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
868 tcg_gen_ext32s_i64(temp64, temp64); /* low */
869 tcg_gen_sub_i64(temp64, temp64_2, temp64);
870 tcg_gen_shli_i64(temp64, temp64, 16);
871 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
873 gen_helper_add64_ssov(temp64, cpu_env, temp64_2, temp64);
874 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
876 tcg_temp_free(temp);
877 tcg_temp_free_i64(temp64);
878 tcg_temp_free_i64(temp64_2);
882 static inline void
883 gen_maddm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
884 TCGv r3, uint32_t n, uint32_t mode)
886 TCGv temp = tcg_const_i32(n);
887 TCGv_i64 temp64 = tcg_temp_new_i64();
888 TCGv_i64 temp64_2 = tcg_temp_new_i64();
889 TCGv_i64 temp64_3 = tcg_temp_new_i64();
890 switch (mode) {
891 case MODE_LL:
892 GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
893 break;
894 case MODE_LU:
895 GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
896 break;
897 case MODE_UL:
898 GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
899 break;
900 case MODE_UU:
901 GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
902 break;
904 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
905 gen_add64_d(temp64_3, temp64_2, temp64);
906 /* write back result */
907 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
909 tcg_temp_free(temp);
910 tcg_temp_free_i64(temp64);
911 tcg_temp_free_i64(temp64_2);
912 tcg_temp_free_i64(temp64_3);
915 static inline void
916 gen_maddms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
917 TCGv r3, uint32_t n, uint32_t mode)
919 TCGv temp = tcg_const_i32(n);
920 TCGv_i64 temp64 = tcg_temp_new_i64();
921 TCGv_i64 temp64_2 = tcg_temp_new_i64();
922 switch (mode) {
923 case MODE_LL:
924 GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
925 break;
926 case MODE_LU:
927 GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
928 break;
929 case MODE_UL:
930 GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
931 break;
932 case MODE_UU:
933 GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
934 break;
936 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
937 gen_helper_add64_ssov(temp64, cpu_env, temp64_2, temp64);
938 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
940 tcg_temp_free(temp);
941 tcg_temp_free_i64(temp64);
942 tcg_temp_free_i64(temp64_2);
945 static inline void
946 gen_maddr64_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n,
947 uint32_t mode)
949 TCGv temp = tcg_const_i32(n);
950 TCGv_i64 temp64 = tcg_temp_new_i64();
951 switch (mode) {
952 case MODE_LL:
953 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
954 break;
955 case MODE_LU:
956 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
957 break;
958 case MODE_UL:
959 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
960 break;
961 case MODE_UU:
962 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
963 break;
965 gen_helper_addr_h(ret, cpu_env, temp64, r1_low, r1_high);
967 tcg_temp_free(temp);
968 tcg_temp_free_i64(temp64);
971 static inline void
972 gen_maddr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
974 TCGv temp = tcg_temp_new();
975 TCGv temp2 = tcg_temp_new();
977 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
978 tcg_gen_shli_tl(temp, r1, 16);
979 gen_maddr64_h(ret, temp, temp2, r2, r3, n, mode);
981 tcg_temp_free(temp);
982 tcg_temp_free(temp2);
985 static inline void
986 gen_maddsur32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
988 TCGv temp = tcg_const_i32(n);
989 TCGv temp2 = tcg_temp_new();
990 TCGv_i64 temp64 = tcg_temp_new_i64();
991 switch (mode) {
992 case MODE_LL:
993 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
994 break;
995 case MODE_LU:
996 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
997 break;
998 case MODE_UL:
999 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1000 break;
1001 case MODE_UU:
1002 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1003 break;
1005 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1006 tcg_gen_shli_tl(temp, r1, 16);
1007 gen_helper_addsur_h(ret, cpu_env, temp64, temp, temp2);
1009 tcg_temp_free(temp);
1010 tcg_temp_free(temp2);
1011 tcg_temp_free_i64(temp64);
1015 static inline void
1016 gen_maddr64s_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3,
1017 uint32_t n, uint32_t mode)
1019 TCGv temp = tcg_const_i32(n);
1020 TCGv_i64 temp64 = tcg_temp_new_i64();
1021 switch (mode) {
1022 case MODE_LL:
1023 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1024 break;
1025 case MODE_LU:
1026 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1027 break;
1028 case MODE_UL:
1029 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1030 break;
1031 case MODE_UU:
1032 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1033 break;
1035 gen_helper_addr_h_ssov(ret, cpu_env, temp64, r1_low, r1_high);
1037 tcg_temp_free(temp);
1038 tcg_temp_free_i64(temp64);
1041 static inline void
1042 gen_maddr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1044 TCGv temp = tcg_temp_new();
1045 TCGv temp2 = tcg_temp_new();
1047 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1048 tcg_gen_shli_tl(temp, r1, 16);
1049 gen_maddr64s_h(ret, temp, temp2, r2, r3, n, mode);
1051 tcg_temp_free(temp);
1052 tcg_temp_free(temp2);
1055 static inline void
1056 gen_maddsur32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1058 TCGv temp = tcg_const_i32(n);
1059 TCGv temp2 = tcg_temp_new();
1060 TCGv_i64 temp64 = tcg_temp_new_i64();
1061 switch (mode) {
1062 case MODE_LL:
1063 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1064 break;
1065 case MODE_LU:
1066 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1067 break;
1068 case MODE_UL:
1069 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1070 break;
1071 case MODE_UU:
1072 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1073 break;
1075 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1076 tcg_gen_shli_tl(temp, r1, 16);
1077 gen_helper_addsur_h_ssov(ret, cpu_env, temp64, temp, temp2);
1079 tcg_temp_free(temp);
1080 tcg_temp_free(temp2);
1081 tcg_temp_free_i64(temp64);
1084 static inline void
1085 gen_maddr_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1087 TCGv temp = tcg_const_i32(n);
1088 gen_helper_maddr_q(ret, cpu_env, r1, r2, r3, temp);
1089 tcg_temp_free(temp);
1092 static inline void
1093 gen_maddrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1095 TCGv temp = tcg_const_i32(n);
1096 gen_helper_maddr_q_ssov(ret, cpu_env, r1, r2, r3, temp);
1097 tcg_temp_free(temp);
1100 static inline void
1101 gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1102 uint32_t up_shift)
1104 TCGv temp = tcg_temp_new();
1105 TCGv temp2 = tcg_temp_new();
1106 TCGv temp3 = tcg_temp_new();
1107 TCGv_i64 t1 = tcg_temp_new_i64();
1108 TCGv_i64 t2 = tcg_temp_new_i64();
1109 TCGv_i64 t3 = tcg_temp_new_i64();
1111 tcg_gen_ext_i32_i64(t2, arg2);
1112 tcg_gen_ext_i32_i64(t3, arg3);
1114 tcg_gen_mul_i64(t2, t2, t3);
1115 tcg_gen_shli_i64(t2, t2, n);
1117 tcg_gen_ext_i32_i64(t1, arg1);
1118 tcg_gen_sari_i64(t2, t2, up_shift);
1120 tcg_gen_add_i64(t3, t1, t2);
1121 tcg_gen_extrl_i64_i32(temp3, t3);
1122 /* calc v bit */
1123 tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1124 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1125 tcg_gen_or_i64(t1, t1, t2);
1126 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1127 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1128 /* We produce an overflow on the host if the mul before was
1129 (0x80000000 * 0x80000000) << 1). If this is the
1130 case, we negate the ovf. */
1131 if (n == 1) {
1132 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
1133 tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
1134 tcg_gen_and_tl(temp, temp, temp2);
1135 tcg_gen_shli_tl(temp, temp, 31);
1136 /* negate v bit, if special condition */
1137 tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
1139 /* Calc SV bit */
1140 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1141 /* Calc AV/SAV bits */
1142 tcg_gen_add_tl(cpu_PSW_AV, temp3, temp3);
1143 tcg_gen_xor_tl(cpu_PSW_AV, temp3, cpu_PSW_AV);
1144 /* calc SAV */
1145 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1146 /* write back result */
1147 tcg_gen_mov_tl(ret, temp3);
1149 tcg_temp_free(temp);
1150 tcg_temp_free(temp2);
1151 tcg_temp_free(temp3);
1152 tcg_temp_free_i64(t1);
1153 tcg_temp_free_i64(t2);
1154 tcg_temp_free_i64(t3);
1157 static inline void
1158 gen_m16add32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
1160 TCGv temp = tcg_temp_new();
1161 TCGv temp2 = tcg_temp_new();
1162 if (n == 0) {
1163 tcg_gen_mul_tl(temp, arg2, arg3);
1164 } else { /* n is expected to be 1 */
1165 tcg_gen_mul_tl(temp, arg2, arg3);
1166 tcg_gen_shli_tl(temp, temp, 1);
1167 /* catch special case r1 = r2 = 0x8000 */
1168 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1169 tcg_gen_sub_tl(temp, temp, temp2);
1171 gen_add_d(ret, arg1, temp);
1173 tcg_temp_free(temp);
1174 tcg_temp_free(temp2);
1177 static inline void
1178 gen_m16adds32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
1180 TCGv temp = tcg_temp_new();
1181 TCGv temp2 = tcg_temp_new();
1182 if (n == 0) {
1183 tcg_gen_mul_tl(temp, arg2, arg3);
1184 } else { /* n is expected to be 1 */
1185 tcg_gen_mul_tl(temp, arg2, arg3);
1186 tcg_gen_shli_tl(temp, temp, 1);
1187 /* catch special case r1 = r2 = 0x8000 */
1188 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1189 tcg_gen_sub_tl(temp, temp, temp2);
1191 gen_adds(ret, arg1, temp);
1193 tcg_temp_free(temp);
1194 tcg_temp_free(temp2);
1197 static inline void
1198 gen_m16add64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1199 TCGv arg3, uint32_t n)
1201 TCGv temp = tcg_temp_new();
1202 TCGv temp2 = tcg_temp_new();
1203 TCGv_i64 t1 = tcg_temp_new_i64();
1204 TCGv_i64 t2 = tcg_temp_new_i64();
1205 TCGv_i64 t3 = tcg_temp_new_i64();
1207 if (n == 0) {
1208 tcg_gen_mul_tl(temp, arg2, arg3);
1209 } else { /* n is expected to be 1 */
1210 tcg_gen_mul_tl(temp, arg2, arg3);
1211 tcg_gen_shli_tl(temp, temp, 1);
1212 /* catch special case r1 = r2 = 0x8000 */
1213 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1214 tcg_gen_sub_tl(temp, temp, temp2);
1216 tcg_gen_ext_i32_i64(t2, temp);
1217 tcg_gen_shli_i64(t2, t2, 16);
1218 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1219 gen_add64_d(t3, t1, t2);
1220 /* write back result */
1221 tcg_gen_extr_i64_i32(rl, rh, t3);
1223 tcg_temp_free_i64(t1);
1224 tcg_temp_free_i64(t2);
1225 tcg_temp_free_i64(t3);
1226 tcg_temp_free(temp);
1227 tcg_temp_free(temp2);
1230 static inline void
1231 gen_m16adds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1232 TCGv arg3, uint32_t n)
1234 TCGv temp = tcg_temp_new();
1235 TCGv temp2 = tcg_temp_new();
1236 TCGv_i64 t1 = tcg_temp_new_i64();
1237 TCGv_i64 t2 = tcg_temp_new_i64();
1239 if (n == 0) {
1240 tcg_gen_mul_tl(temp, arg2, arg3);
1241 } else { /* n is expected to be 1 */
1242 tcg_gen_mul_tl(temp, arg2, arg3);
1243 tcg_gen_shli_tl(temp, temp, 1);
1244 /* catch special case r1 = r2 = 0x8000 */
1245 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1246 tcg_gen_sub_tl(temp, temp, temp2);
1248 tcg_gen_ext_i32_i64(t2, temp);
1249 tcg_gen_shli_i64(t2, t2, 16);
1250 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1252 gen_helper_add64_ssov(t1, cpu_env, t1, t2);
1253 tcg_gen_extr_i64_i32(rl, rh, t1);
1255 tcg_temp_free(temp);
1256 tcg_temp_free(temp2);
1257 tcg_temp_free_i64(t1);
1258 tcg_temp_free_i64(t2);
1261 static inline void
1262 gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1263 TCGv arg3, uint32_t n)
1265 TCGv_i64 t1 = tcg_temp_new_i64();
1266 TCGv_i64 t2 = tcg_temp_new_i64();
1267 TCGv_i64 t3 = tcg_temp_new_i64();
1268 TCGv_i64 t4 = tcg_temp_new_i64();
1269 TCGv temp, temp2;
1271 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1272 tcg_gen_ext_i32_i64(t2, arg2);
1273 tcg_gen_ext_i32_i64(t3, arg3);
1275 tcg_gen_mul_i64(t2, t2, t3);
1276 if (n != 0) {
1277 tcg_gen_shli_i64(t2, t2, 1);
1279 tcg_gen_add_i64(t4, t1, t2);
1280 /* calc v bit */
1281 tcg_gen_xor_i64(t3, t4, t1);
1282 tcg_gen_xor_i64(t2, t1, t2);
1283 tcg_gen_andc_i64(t3, t3, t2);
1284 tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
1285 /* We produce an overflow on the host if the mul before was
1286 (0x80000000 * 0x80000000) << 1). If this is the
1287 case, we negate the ovf. */
1288 if (n == 1) {
1289 temp = tcg_temp_new();
1290 temp2 = tcg_temp_new();
1291 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
1292 tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
1293 tcg_gen_and_tl(temp, temp, temp2);
1294 tcg_gen_shli_tl(temp, temp, 31);
1295 /* negate v bit, if special condition */
1296 tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
1298 tcg_temp_free(temp);
1299 tcg_temp_free(temp2);
1301 /* write back result */
1302 tcg_gen_extr_i64_i32(rl, rh, t4);
1303 /* Calc SV bit */
1304 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1305 /* Calc AV/SAV bits */
1306 tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
1307 tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
1308 /* calc SAV */
1309 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1311 tcg_temp_free_i64(t1);
1312 tcg_temp_free_i64(t2);
1313 tcg_temp_free_i64(t3);
1314 tcg_temp_free_i64(t4);
1317 static inline void
1318 gen_madds32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1319 uint32_t up_shift)
1321 TCGv_i64 t1 = tcg_temp_new_i64();
1322 TCGv_i64 t2 = tcg_temp_new_i64();
1323 TCGv_i64 t3 = tcg_temp_new_i64();
1325 tcg_gen_ext_i32_i64(t1, arg1);
1326 tcg_gen_ext_i32_i64(t2, arg2);
1327 tcg_gen_ext_i32_i64(t3, arg3);
1329 tcg_gen_mul_i64(t2, t2, t3);
1330 tcg_gen_sari_i64(t2, t2, up_shift - n);
1332 gen_helper_madd32_q_add_ssov(ret, cpu_env, t1, t2);
1334 tcg_temp_free_i64(t1);
1335 tcg_temp_free_i64(t2);
1336 tcg_temp_free_i64(t3);
1339 static inline void
1340 gen_madds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1341 TCGv arg3, uint32_t n)
1343 TCGv_i64 r1 = tcg_temp_new_i64();
1344 TCGv temp = tcg_const_i32(n);
1346 tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
1347 gen_helper_madd64_q_ssov(r1, cpu_env, r1, arg2, arg3, temp);
1348 tcg_gen_extr_i64_i32(rl, rh, r1);
1350 tcg_temp_free_i64(r1);
1351 tcg_temp_free(temp);
1353 /* ret = r2 - (r1 * r3); */
1354 static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
1356 TCGv_i64 t1 = tcg_temp_new_i64();
1357 TCGv_i64 t2 = tcg_temp_new_i64();
1358 TCGv_i64 t3 = tcg_temp_new_i64();
1360 tcg_gen_ext_i32_i64(t1, r1);
1361 tcg_gen_ext_i32_i64(t2, r2);
1362 tcg_gen_ext_i32_i64(t3, r3);
1364 tcg_gen_mul_i64(t1, t1, t3);
1365 tcg_gen_sub_i64(t1, t2, t1);
1367 tcg_gen_extrl_i64_i32(ret, t1);
1368 /* calc V
1369 t2 > 0x7fffffff */
1370 tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
1371 /* result < -0x80000000 */
1372 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
1373 tcg_gen_or_i64(t2, t2, t3);
1374 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
1375 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1377 /* Calc SV bit */
1378 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1379 /* Calc AV/SAV bits */
1380 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
1381 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
1382 /* calc SAV */
1383 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1385 tcg_temp_free_i64(t1);
1386 tcg_temp_free_i64(t2);
1387 tcg_temp_free_i64(t3);
1390 static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
1392 TCGv temp = tcg_const_i32(con);
1393 gen_msub32_d(ret, r1, r2, temp);
1394 tcg_temp_free(temp);
1397 static inline void
1398 gen_msub64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1399 TCGv r3)
1401 TCGv t1 = tcg_temp_new();
1402 TCGv t2 = tcg_temp_new();
1403 TCGv t3 = tcg_temp_new();
1404 TCGv t4 = tcg_temp_new();
1406 tcg_gen_muls2_tl(t1, t2, r1, r3);
1407 /* only the sub can overflow */
1408 tcg_gen_sub2_tl(t3, t4, r2_low, r2_high, t1, t2);
1409 /* calc V bit */
1410 tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
1411 tcg_gen_xor_tl(t1, r2_high, t2);
1412 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, t1);
1413 /* Calc SV bit */
1414 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1415 /* Calc AV/SAV bits */
1416 tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
1417 tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
1418 /* calc SAV */
1419 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1420 /* write back the result */
1421 tcg_gen_mov_tl(ret_low, t3);
1422 tcg_gen_mov_tl(ret_high, t4);
1424 tcg_temp_free(t1);
1425 tcg_temp_free(t2);
1426 tcg_temp_free(t3);
1427 tcg_temp_free(t4);
1430 static inline void
1431 gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1432 int32_t con)
1434 TCGv temp = tcg_const_i32(con);
1435 gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1436 tcg_temp_free(temp);
1439 static inline void
1440 gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1441 TCGv r3)
1443 TCGv_i64 t1 = tcg_temp_new_i64();
1444 TCGv_i64 t2 = tcg_temp_new_i64();
1445 TCGv_i64 t3 = tcg_temp_new_i64();
1447 tcg_gen_extu_i32_i64(t1, r1);
1448 tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
1449 tcg_gen_extu_i32_i64(t3, r3);
1451 tcg_gen_mul_i64(t1, t1, t3);
1452 tcg_gen_sub_i64(t3, t2, t1);
1453 tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
1454 /* calc V bit, only the sub can overflow, if t1 > t2 */
1455 tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
1456 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1457 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1458 /* Calc SV bit */
1459 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1460 /* Calc AV/SAV bits */
1461 tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
1462 tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
1463 /* calc SAV */
1464 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1466 tcg_temp_free_i64(t1);
1467 tcg_temp_free_i64(t2);
1468 tcg_temp_free_i64(t3);
1471 static inline void
1472 gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1473 int32_t con)
1475 TCGv temp = tcg_const_i32(con);
1476 gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1477 tcg_temp_free(temp);
1480 static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
1482 TCGv temp = tcg_const_i32(r2);
1483 gen_add_d(ret, r1, temp);
1484 tcg_temp_free(temp);
1486 /* calculate the carry bit too */
1487 static inline void gen_add_CC(TCGv ret, TCGv r1, TCGv r2)
1489 TCGv t0 = tcg_temp_new_i32();
1490 TCGv result = tcg_temp_new_i32();
1492 tcg_gen_movi_tl(t0, 0);
1493 /* Addition and set C/V/SV bits */
1494 tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, r2, t0);
1495 /* calc V bit */
1496 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1497 tcg_gen_xor_tl(t0, r1, r2);
1498 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
1499 /* Calc SV bit */
1500 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1501 /* Calc AV/SAV bits */
1502 tcg_gen_add_tl(cpu_PSW_AV, result, result);
1503 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1504 /* calc SAV */
1505 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1506 /* write back result */
1507 tcg_gen_mov_tl(ret, result);
1509 tcg_temp_free(result);
1510 tcg_temp_free(t0);
1513 static inline void gen_addi_CC(TCGv ret, TCGv r1, int32_t con)
1515 TCGv temp = tcg_const_i32(con);
1516 gen_add_CC(ret, r1, temp);
1517 tcg_temp_free(temp);
1520 static inline void gen_addc_CC(TCGv ret, TCGv r1, TCGv r2)
1522 TCGv carry = tcg_temp_new_i32();
1523 TCGv t0 = tcg_temp_new_i32();
1524 TCGv result = tcg_temp_new_i32();
1526 tcg_gen_movi_tl(t0, 0);
1527 tcg_gen_setcondi_tl(TCG_COND_NE, carry, cpu_PSW_C, 0);
1528 /* Addition, carry and set C/V/SV bits */
1529 tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, carry, t0);
1530 tcg_gen_add2_i32(result, cpu_PSW_C, result, cpu_PSW_C, r2, t0);
1531 /* calc V bit */
1532 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1533 tcg_gen_xor_tl(t0, r1, r2);
1534 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
1535 /* Calc SV bit */
1536 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1537 /* Calc AV/SAV bits */
1538 tcg_gen_add_tl(cpu_PSW_AV, result, result);
1539 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1540 /* calc SAV */
1541 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1542 /* write back result */
1543 tcg_gen_mov_tl(ret, result);
1545 tcg_temp_free(result);
1546 tcg_temp_free(t0);
1547 tcg_temp_free(carry);
1550 static inline void gen_addci_CC(TCGv ret, TCGv r1, int32_t con)
1552 TCGv temp = tcg_const_i32(con);
1553 gen_addc_CC(ret, r1, temp);
1554 tcg_temp_free(temp);
1557 static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
1558 TCGv r4)
1560 TCGv temp = tcg_temp_new();
1561 TCGv temp2 = tcg_temp_new();
1562 TCGv result = tcg_temp_new();
1563 TCGv mask = tcg_temp_new();
1564 TCGv t0 = tcg_const_i32(0);
1566 /* create mask for sticky bits */
1567 tcg_gen_setcond_tl(cond, mask, r4, t0);
1568 tcg_gen_shli_tl(mask, mask, 31);
1570 tcg_gen_add_tl(result, r1, r2);
1571 /* Calc PSW_V */
1572 tcg_gen_xor_tl(temp, result, r1);
1573 tcg_gen_xor_tl(temp2, r1, r2);
1574 tcg_gen_andc_tl(temp, temp, temp2);
1575 tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1576 /* Set PSW_SV */
1577 tcg_gen_and_tl(temp, temp, mask);
1578 tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
1579 /* calc AV bit */
1580 tcg_gen_add_tl(temp, result, result);
1581 tcg_gen_xor_tl(temp, temp, result);
1582 tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1583 /* calc SAV bit */
1584 tcg_gen_and_tl(temp, temp, mask);
1585 tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1586 /* write back result */
1587 tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
1589 tcg_temp_free(t0);
1590 tcg_temp_free(temp);
1591 tcg_temp_free(temp2);
1592 tcg_temp_free(result);
1593 tcg_temp_free(mask);
1596 static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
1597 TCGv r3, TCGv r4)
1599 TCGv temp = tcg_const_i32(r2);
1600 gen_cond_add(cond, r1, temp, r3, r4);
1601 tcg_temp_free(temp);
1604 static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
1606 TCGv temp = tcg_temp_new_i32();
1607 TCGv result = tcg_temp_new_i32();
1609 tcg_gen_sub_tl(result, r1, r2);
1610 /* calc V bit */
1611 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1612 tcg_gen_xor_tl(temp, r1, r2);
1613 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
1614 /* calc SV bit */
1615 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1616 /* Calc AV bit */
1617 tcg_gen_add_tl(cpu_PSW_AV, result, result);
1618 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1619 /* calc SAV bit */
1620 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1621 /* write back result */
1622 tcg_gen_mov_tl(ret, result);
1624 tcg_temp_free(temp);
1625 tcg_temp_free(result);
1628 static inline void
1629 gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
1631 TCGv temp = tcg_temp_new();
1632 TCGv_i64 t0 = tcg_temp_new_i64();
1633 TCGv_i64 t1 = tcg_temp_new_i64();
1634 TCGv_i64 result = tcg_temp_new_i64();
1636 tcg_gen_sub_i64(result, r1, r2);
1637 /* calc v bit */
1638 tcg_gen_xor_i64(t1, result, r1);
1639 tcg_gen_xor_i64(t0, r1, r2);
1640 tcg_gen_and_i64(t1, t1, t0);
1641 tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
1642 /* calc SV bit */
1643 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1644 /* calc AV/SAV bits */
1645 tcg_gen_extrh_i64_i32(temp, result);
1646 tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
1647 tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
1648 /* calc SAV */
1649 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1650 /* write back result */
1651 tcg_gen_mov_i64(ret, result);
1653 tcg_temp_free(temp);
1654 tcg_temp_free_i64(result);
1655 tcg_temp_free_i64(t0);
1656 tcg_temp_free_i64(t1);
1659 static inline void gen_sub_CC(TCGv ret, TCGv r1, TCGv r2)
1661 TCGv result = tcg_temp_new();
1662 TCGv temp = tcg_temp_new();
1664 tcg_gen_sub_tl(result, r1, r2);
1665 /* calc C bit */
1666 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_PSW_C, r1, r2);
1667 /* calc V bit */
1668 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1669 tcg_gen_xor_tl(temp, r1, r2);
1670 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
1671 /* calc SV bit */
1672 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1673 /* Calc AV bit */
1674 tcg_gen_add_tl(cpu_PSW_AV, result, result);
1675 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1676 /* calc SAV bit */
1677 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1678 /* write back result */
1679 tcg_gen_mov_tl(ret, result);
1681 tcg_temp_free(result);
1682 tcg_temp_free(temp);
1685 static inline void gen_subc_CC(TCGv ret, TCGv r1, TCGv r2)
1687 TCGv temp = tcg_temp_new();
1688 tcg_gen_not_tl(temp, r2);
1689 gen_addc_CC(ret, r1, temp);
1690 tcg_temp_free(temp);
1693 static inline void gen_cond_sub(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
1694 TCGv r4)
1696 TCGv temp = tcg_temp_new();
1697 TCGv temp2 = tcg_temp_new();
1698 TCGv result = tcg_temp_new();
1699 TCGv mask = tcg_temp_new();
1700 TCGv t0 = tcg_const_i32(0);
1702 /* create mask for sticky bits */
1703 tcg_gen_setcond_tl(cond, mask, r4, t0);
1704 tcg_gen_shli_tl(mask, mask, 31);
1706 tcg_gen_sub_tl(result, r1, r2);
1707 /* Calc PSW_V */
1708 tcg_gen_xor_tl(temp, result, r1);
1709 tcg_gen_xor_tl(temp2, r1, r2);
1710 tcg_gen_and_tl(temp, temp, temp2);
1711 tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1712 /* Set PSW_SV */
1713 tcg_gen_and_tl(temp, temp, mask);
1714 tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
1715 /* calc AV bit */
1716 tcg_gen_add_tl(temp, result, result);
1717 tcg_gen_xor_tl(temp, temp, result);
1718 tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1719 /* calc SAV bit */
1720 tcg_gen_and_tl(temp, temp, mask);
1721 tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1722 /* write back result */
1723 tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
1725 tcg_temp_free(t0);
1726 tcg_temp_free(temp);
1727 tcg_temp_free(temp2);
1728 tcg_temp_free(result);
1729 tcg_temp_free(mask);
1732 static inline void
1733 gen_msub_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1734 TCGv r3, uint32_t n, uint32_t mode)
1736 TCGv temp = tcg_const_i32(n);
1737 TCGv temp2 = tcg_temp_new();
1738 TCGv_i64 temp64 = tcg_temp_new_i64();
1739 switch (mode) {
1740 case MODE_LL:
1741 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1742 break;
1743 case MODE_LU:
1744 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1745 break;
1746 case MODE_UL:
1747 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1748 break;
1749 case MODE_UU:
1750 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1751 break;
1753 tcg_gen_extr_i64_i32(temp, temp2, temp64);
1754 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
1755 tcg_gen_sub_tl, tcg_gen_sub_tl);
1756 tcg_temp_free(temp);
1757 tcg_temp_free(temp2);
1758 tcg_temp_free_i64(temp64);
1761 static inline void
1762 gen_msubs_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1763 TCGv r3, uint32_t n, uint32_t mode)
1765 TCGv temp = tcg_const_i32(n);
1766 TCGv temp2 = tcg_temp_new();
1767 TCGv temp3 = tcg_temp_new();
1768 TCGv_i64 temp64 = tcg_temp_new_i64();
1770 switch (mode) {
1771 case MODE_LL:
1772 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1773 break;
1774 case MODE_LU:
1775 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1776 break;
1777 case MODE_UL:
1778 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1779 break;
1780 case MODE_UU:
1781 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1782 break;
1784 tcg_gen_extr_i64_i32(temp, temp2, temp64);
1785 gen_subs(ret_low, r1_low, temp);
1786 tcg_gen_mov_tl(temp, cpu_PSW_V);
1787 tcg_gen_mov_tl(temp3, cpu_PSW_AV);
1788 gen_subs(ret_high, r1_high, temp2);
1789 /* combine v bits */
1790 tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
1791 /* combine av bits */
1792 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
1794 tcg_temp_free(temp);
1795 tcg_temp_free(temp2);
1796 tcg_temp_free(temp3);
1797 tcg_temp_free_i64(temp64);
1800 static inline void
1801 gen_msubm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1802 TCGv r3, uint32_t n, uint32_t mode)
1804 TCGv temp = tcg_const_i32(n);
1805 TCGv_i64 temp64 = tcg_temp_new_i64();
1806 TCGv_i64 temp64_2 = tcg_temp_new_i64();
1807 TCGv_i64 temp64_3 = tcg_temp_new_i64();
1808 switch (mode) {
1809 case MODE_LL:
1810 GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
1811 break;
1812 case MODE_LU:
1813 GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
1814 break;
1815 case MODE_UL:
1816 GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
1817 break;
1818 case MODE_UU:
1819 GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
1820 break;
1822 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1823 gen_sub64_d(temp64_3, temp64_2, temp64);
1824 /* write back result */
1825 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
1827 tcg_temp_free(temp);
1828 tcg_temp_free_i64(temp64);
1829 tcg_temp_free_i64(temp64_2);
1830 tcg_temp_free_i64(temp64_3);
1833 static inline void
1834 gen_msubms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1835 TCGv r3, uint32_t n, uint32_t mode)
1837 TCGv temp = tcg_const_i32(n);
1838 TCGv_i64 temp64 = tcg_temp_new_i64();
1839 TCGv_i64 temp64_2 = tcg_temp_new_i64();
1840 switch (mode) {
1841 case MODE_LL:
1842 GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
1843 break;
1844 case MODE_LU:
1845 GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
1846 break;
1847 case MODE_UL:
1848 GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
1849 break;
1850 case MODE_UU:
1851 GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
1852 break;
1854 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1855 gen_helper_sub64_ssov(temp64, cpu_env, temp64_2, temp64);
1856 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
1858 tcg_temp_free(temp);
1859 tcg_temp_free_i64(temp64);
1860 tcg_temp_free_i64(temp64_2);
1863 static inline void
1864 gen_msubr64_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n,
1865 uint32_t mode)
1867 TCGv temp = tcg_const_i32(n);
1868 TCGv_i64 temp64 = tcg_temp_new_i64();
1869 switch (mode) {
1870 case MODE_LL:
1871 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1872 break;
1873 case MODE_LU:
1874 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1875 break;
1876 case MODE_UL:
1877 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1878 break;
1879 case MODE_UU:
1880 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1881 break;
1883 gen_helper_subr_h(ret, cpu_env, temp64, r1_low, r1_high);
1885 tcg_temp_free(temp);
1886 tcg_temp_free_i64(temp64);
1889 static inline void
1890 gen_msubr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1892 TCGv temp = tcg_temp_new();
1893 TCGv temp2 = tcg_temp_new();
1895 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1896 tcg_gen_shli_tl(temp, r1, 16);
1897 gen_msubr64_h(ret, temp, temp2, r2, r3, n, mode);
1899 tcg_temp_free(temp);
1900 tcg_temp_free(temp2);
1903 static inline void
1904 gen_msubr64s_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3,
1905 uint32_t n, uint32_t mode)
1907 TCGv temp = tcg_const_i32(n);
1908 TCGv_i64 temp64 = tcg_temp_new_i64();
1909 switch (mode) {
1910 case MODE_LL:
1911 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1912 break;
1913 case MODE_LU:
1914 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1915 break;
1916 case MODE_UL:
1917 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1918 break;
1919 case MODE_UU:
1920 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1921 break;
1923 gen_helper_subr_h_ssov(ret, cpu_env, temp64, r1_low, r1_high);
1925 tcg_temp_free(temp);
1926 tcg_temp_free_i64(temp64);
1929 static inline void
1930 gen_msubr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1932 TCGv temp = tcg_temp_new();
1933 TCGv temp2 = tcg_temp_new();
1935 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1936 tcg_gen_shli_tl(temp, r1, 16);
1937 gen_msubr64s_h(ret, temp, temp2, r2, r3, n, mode);
1939 tcg_temp_free(temp);
1940 tcg_temp_free(temp2);
1943 static inline void
1944 gen_msubr_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1946 TCGv temp = tcg_const_i32(n);
1947 gen_helper_msubr_q(ret, cpu_env, r1, r2, r3, temp);
1948 tcg_temp_free(temp);
1951 static inline void
1952 gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1954 TCGv temp = tcg_const_i32(n);
1955 gen_helper_msubr_q_ssov(ret, cpu_env, r1, r2, r3, temp);
1956 tcg_temp_free(temp);
1959 static inline void
1960 gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1961 uint32_t up_shift)
1963 TCGv temp = tcg_temp_new();
1964 TCGv temp2 = tcg_temp_new();
1965 TCGv temp3 = tcg_temp_new();
1966 TCGv_i64 t1 = tcg_temp_new_i64();
1967 TCGv_i64 t2 = tcg_temp_new_i64();
1968 TCGv_i64 t3 = tcg_temp_new_i64();
1969 TCGv_i64 t4 = tcg_temp_new_i64();
1971 tcg_gen_ext_i32_i64(t2, arg2);
1972 tcg_gen_ext_i32_i64(t3, arg3);
1974 tcg_gen_mul_i64(t2, t2, t3);
1976 tcg_gen_ext_i32_i64(t1, arg1);
1977 /* if we shift part of the fraction out, we need to round up */
1978 tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
1979 tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
1980 tcg_gen_sari_i64(t2, t2, up_shift - n);
1981 tcg_gen_add_i64(t2, t2, t4);
1983 tcg_gen_sub_i64(t3, t1, t2);
1984 tcg_gen_extrl_i64_i32(temp3, t3);
1985 /* calc v bit */
1986 tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1987 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1988 tcg_gen_or_i64(t1, t1, t2);
1989 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1990 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1991 /* Calc SV bit */
1992 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1993 /* Calc AV/SAV bits */
1994 tcg_gen_add_tl(cpu_PSW_AV, temp3, temp3);
1995 tcg_gen_xor_tl(cpu_PSW_AV, temp3, cpu_PSW_AV);
1996 /* calc SAV */
1997 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1998 /* write back result */
1999 tcg_gen_mov_tl(ret, temp3);
2001 tcg_temp_free(temp);
2002 tcg_temp_free(temp2);
2003 tcg_temp_free(temp3);
2004 tcg_temp_free_i64(t1);
2005 tcg_temp_free_i64(t2);
2006 tcg_temp_free_i64(t3);
2007 tcg_temp_free_i64(t4);
2010 static inline void
2011 gen_m16sub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
2013 TCGv temp = tcg_temp_new();
2014 TCGv temp2 = tcg_temp_new();
2015 if (n == 0) {
2016 tcg_gen_mul_tl(temp, arg2, arg3);
2017 } else { /* n is expected to be 1 */
2018 tcg_gen_mul_tl(temp, arg2, arg3);
2019 tcg_gen_shli_tl(temp, temp, 1);
2020 /* catch special case r1 = r2 = 0x8000 */
2021 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2022 tcg_gen_sub_tl(temp, temp, temp2);
2024 gen_sub_d(ret, arg1, temp);
2026 tcg_temp_free(temp);
2027 tcg_temp_free(temp2);
2030 static inline void
2031 gen_m16subs32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
2033 TCGv temp = tcg_temp_new();
2034 TCGv temp2 = tcg_temp_new();
2035 if (n == 0) {
2036 tcg_gen_mul_tl(temp, arg2, arg3);
2037 } else { /* n is expected to be 1 */
2038 tcg_gen_mul_tl(temp, arg2, arg3);
2039 tcg_gen_shli_tl(temp, temp, 1);
2040 /* catch special case r1 = r2 = 0x8000 */
2041 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2042 tcg_gen_sub_tl(temp, temp, temp2);
2044 gen_subs(ret, arg1, temp);
2046 tcg_temp_free(temp);
2047 tcg_temp_free(temp2);
2050 static inline void
2051 gen_m16sub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2052 TCGv arg3, uint32_t n)
2054 TCGv temp = tcg_temp_new();
2055 TCGv temp2 = tcg_temp_new();
2056 TCGv_i64 t1 = tcg_temp_new_i64();
2057 TCGv_i64 t2 = tcg_temp_new_i64();
2058 TCGv_i64 t3 = tcg_temp_new_i64();
2060 if (n == 0) {
2061 tcg_gen_mul_tl(temp, arg2, arg3);
2062 } else { /* n is expected to be 1 */
2063 tcg_gen_mul_tl(temp, arg2, arg3);
2064 tcg_gen_shli_tl(temp, temp, 1);
2065 /* catch special case r1 = r2 = 0x8000 */
2066 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2067 tcg_gen_sub_tl(temp, temp, temp2);
2069 tcg_gen_ext_i32_i64(t2, temp);
2070 tcg_gen_shli_i64(t2, t2, 16);
2071 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2072 gen_sub64_d(t3, t1, t2);
2073 /* write back result */
2074 tcg_gen_extr_i64_i32(rl, rh, t3);
2076 tcg_temp_free_i64(t1);
2077 tcg_temp_free_i64(t2);
2078 tcg_temp_free_i64(t3);
2079 tcg_temp_free(temp);
2080 tcg_temp_free(temp2);
2083 static inline void
2084 gen_m16subs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2085 TCGv arg3, uint32_t n)
2087 TCGv temp = tcg_temp_new();
2088 TCGv temp2 = tcg_temp_new();
2089 TCGv_i64 t1 = tcg_temp_new_i64();
2090 TCGv_i64 t2 = tcg_temp_new_i64();
2092 if (n == 0) {
2093 tcg_gen_mul_tl(temp, arg2, arg3);
2094 } else { /* n is expected to be 1 */
2095 tcg_gen_mul_tl(temp, arg2, arg3);
2096 tcg_gen_shli_tl(temp, temp, 1);
2097 /* catch special case r1 = r2 = 0x8000 */
2098 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2099 tcg_gen_sub_tl(temp, temp, temp2);
2101 tcg_gen_ext_i32_i64(t2, temp);
2102 tcg_gen_shli_i64(t2, t2, 16);
2103 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2105 gen_helper_sub64_ssov(t1, cpu_env, t1, t2);
2106 tcg_gen_extr_i64_i32(rl, rh, t1);
2108 tcg_temp_free(temp);
2109 tcg_temp_free(temp2);
2110 tcg_temp_free_i64(t1);
2111 tcg_temp_free_i64(t2);
2114 static inline void
2115 gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2116 TCGv arg3, uint32_t n)
2118 TCGv_i64 t1 = tcg_temp_new_i64();
2119 TCGv_i64 t2 = tcg_temp_new_i64();
2120 TCGv_i64 t3 = tcg_temp_new_i64();
2121 TCGv_i64 t4 = tcg_temp_new_i64();
2122 TCGv temp, temp2;
2124 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2125 tcg_gen_ext_i32_i64(t2, arg2);
2126 tcg_gen_ext_i32_i64(t3, arg3);
2128 tcg_gen_mul_i64(t2, t2, t3);
2129 if (n != 0) {
2130 tcg_gen_shli_i64(t2, t2, 1);
2132 tcg_gen_sub_i64(t4, t1, t2);
2133 /* calc v bit */
2134 tcg_gen_xor_i64(t3, t4, t1);
2135 tcg_gen_xor_i64(t2, t1, t2);
2136 tcg_gen_and_i64(t3, t3, t2);
2137 tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
2138 /* We produce an overflow on the host if the mul before was
2139 (0x80000000 * 0x80000000) << 1). If this is the
2140 case, we negate the ovf. */
2141 if (n == 1) {
2142 temp = tcg_temp_new();
2143 temp2 = tcg_temp_new();
2144 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
2145 tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
2146 tcg_gen_and_tl(temp, temp, temp2);
2147 tcg_gen_shli_tl(temp, temp, 31);
2148 /* negate v bit, if special condition */
2149 tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
2151 tcg_temp_free(temp);
2152 tcg_temp_free(temp2);
2154 /* write back result */
2155 tcg_gen_extr_i64_i32(rl, rh, t4);
2156 /* Calc SV bit */
2157 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2158 /* Calc AV/SAV bits */
2159 tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
2160 tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
2161 /* calc SAV */
2162 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2164 tcg_temp_free_i64(t1);
2165 tcg_temp_free_i64(t2);
2166 tcg_temp_free_i64(t3);
2167 tcg_temp_free_i64(t4);
2170 static inline void
2171 gen_msubs32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
2172 uint32_t up_shift)
2174 TCGv_i64 t1 = tcg_temp_new_i64();
2175 TCGv_i64 t2 = tcg_temp_new_i64();
2176 TCGv_i64 t3 = tcg_temp_new_i64();
2177 TCGv_i64 t4 = tcg_temp_new_i64();
2179 tcg_gen_ext_i32_i64(t1, arg1);
2180 tcg_gen_ext_i32_i64(t2, arg2);
2181 tcg_gen_ext_i32_i64(t3, arg3);
2183 tcg_gen_mul_i64(t2, t2, t3);
2184 /* if we shift part of the fraction out, we need to round up */
2185 tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
2186 tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
2187 tcg_gen_sari_i64(t3, t2, up_shift - n);
2188 tcg_gen_add_i64(t3, t3, t4);
2190 gen_helper_msub32_q_sub_ssov(ret, cpu_env, t1, t3);
2192 tcg_temp_free_i64(t1);
2193 tcg_temp_free_i64(t2);
2194 tcg_temp_free_i64(t3);
2195 tcg_temp_free_i64(t4);
2198 static inline void
2199 gen_msubs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2200 TCGv arg3, uint32_t n)
2202 TCGv_i64 r1 = tcg_temp_new_i64();
2203 TCGv temp = tcg_const_i32(n);
2205 tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
2206 gen_helper_msub64_q_ssov(r1, cpu_env, r1, arg2, arg3, temp);
2207 tcg_gen_extr_i64_i32(rl, rh, r1);
2209 tcg_temp_free_i64(r1);
2210 tcg_temp_free(temp);
2213 static inline void
2214 gen_msubad_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2215 TCGv r3, uint32_t n, uint32_t mode)
2217 TCGv temp = tcg_const_i32(n);
2218 TCGv temp2 = tcg_temp_new();
2219 TCGv_i64 temp64 = tcg_temp_new_i64();
2220 switch (mode) {
2221 case MODE_LL:
2222 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2223 break;
2224 case MODE_LU:
2225 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2226 break;
2227 case MODE_UL:
2228 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2229 break;
2230 case MODE_UU:
2231 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2232 break;
2234 tcg_gen_extr_i64_i32(temp, temp2, temp64);
2235 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
2236 tcg_gen_add_tl, tcg_gen_sub_tl);
2237 tcg_temp_free(temp);
2238 tcg_temp_free(temp2);
2239 tcg_temp_free_i64(temp64);
2242 static inline void
2243 gen_msubadm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2244 TCGv r3, uint32_t n, uint32_t mode)
2246 TCGv temp = tcg_const_i32(n);
2247 TCGv_i64 temp64 = tcg_temp_new_i64();
2248 TCGv_i64 temp64_2 = tcg_temp_new_i64();
2249 TCGv_i64 temp64_3 = tcg_temp_new_i64();
2250 switch (mode) {
2251 case MODE_LL:
2252 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2253 break;
2254 case MODE_LU:
2255 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2256 break;
2257 case MODE_UL:
2258 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2259 break;
2260 case MODE_UU:
2261 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2262 break;
2264 tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
2265 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2266 tcg_gen_ext32s_i64(temp64, temp64); /* low */
2267 tcg_gen_sub_i64(temp64, temp64_2, temp64);
2268 tcg_gen_shli_i64(temp64, temp64, 16);
2270 gen_sub64_d(temp64_2, temp64_3, temp64);
2271 /* write back result */
2272 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
2274 tcg_temp_free(temp);
2275 tcg_temp_free_i64(temp64);
2276 tcg_temp_free_i64(temp64_2);
2277 tcg_temp_free_i64(temp64_3);
2280 static inline void
2281 gen_msubadr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
2283 TCGv temp = tcg_const_i32(n);
2284 TCGv temp2 = tcg_temp_new();
2285 TCGv_i64 temp64 = tcg_temp_new_i64();
2286 switch (mode) {
2287 case MODE_LL:
2288 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2289 break;
2290 case MODE_LU:
2291 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2292 break;
2293 case MODE_UL:
2294 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2295 break;
2296 case MODE_UU:
2297 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2298 break;
2300 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
2301 tcg_gen_shli_tl(temp, r1, 16);
2302 gen_helper_subadr_h(ret, cpu_env, temp64, temp, temp2);
2304 tcg_temp_free(temp);
2305 tcg_temp_free(temp2);
2306 tcg_temp_free_i64(temp64);
2309 static inline void
2310 gen_msubads_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2311 TCGv r3, uint32_t n, uint32_t mode)
2313 TCGv temp = tcg_const_i32(n);
2314 TCGv temp2 = tcg_temp_new();
2315 TCGv temp3 = tcg_temp_new();
2316 TCGv_i64 temp64 = tcg_temp_new_i64();
2318 switch (mode) {
2319 case MODE_LL:
2320 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2321 break;
2322 case MODE_LU:
2323 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2324 break;
2325 case MODE_UL:
2326 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2327 break;
2328 case MODE_UU:
2329 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2330 break;
2332 tcg_gen_extr_i64_i32(temp, temp2, temp64);
2333 gen_adds(ret_low, r1_low, temp);
2334 tcg_gen_mov_tl(temp, cpu_PSW_V);
2335 tcg_gen_mov_tl(temp3, cpu_PSW_AV);
2336 gen_subs(ret_high, r1_high, temp2);
2337 /* combine v bits */
2338 tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
2339 /* combine av bits */
2340 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
2342 tcg_temp_free(temp);
2343 tcg_temp_free(temp2);
2344 tcg_temp_free(temp3);
2345 tcg_temp_free_i64(temp64);
2348 static inline void
2349 gen_msubadms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2350 TCGv r3, uint32_t n, uint32_t mode)
2352 TCGv temp = tcg_const_i32(n);
2353 TCGv_i64 temp64 = tcg_temp_new_i64();
2354 TCGv_i64 temp64_2 = tcg_temp_new_i64();
2356 switch (mode) {
2357 case MODE_LL:
2358 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2359 break;
2360 case MODE_LU:
2361 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2362 break;
2363 case MODE_UL:
2364 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2365 break;
2366 case MODE_UU:
2367 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2368 break;
2370 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2371 tcg_gen_ext32s_i64(temp64, temp64); /* low */
2372 tcg_gen_sub_i64(temp64, temp64_2, temp64);
2373 tcg_gen_shli_i64(temp64, temp64, 16);
2374 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
2376 gen_helper_sub64_ssov(temp64, cpu_env, temp64_2, temp64);
2377 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2379 tcg_temp_free(temp);
2380 tcg_temp_free_i64(temp64);
2381 tcg_temp_free_i64(temp64_2);
2384 static inline void
2385 gen_msubadr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
2387 TCGv temp = tcg_const_i32(n);
2388 TCGv temp2 = tcg_temp_new();
2389 TCGv_i64 temp64 = tcg_temp_new_i64();
2390 switch (mode) {
2391 case MODE_LL:
2392 GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2393 break;
2394 case MODE_LU:
2395 GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2396 break;
2397 case MODE_UL:
2398 GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2399 break;
2400 case MODE_UU:
2401 GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2402 break;
2404 tcg_gen_andi_tl(temp2, r1, 0xffff0000);
2405 tcg_gen_shli_tl(temp, r1, 16);
2406 gen_helper_subadr_h_ssov(ret, cpu_env, temp64, temp, temp2);
2408 tcg_temp_free(temp);
2409 tcg_temp_free(temp2);
2410 tcg_temp_free_i64(temp64);
2413 static inline void gen_abs(TCGv ret, TCGv r1)
2415 tcg_gen_abs_tl(ret, r1);
2416 /* overflow can only happen, if r1 = 0x80000000 */
2417 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
2418 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2419 /* calc SV bit */
2420 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2421 /* Calc AV bit */
2422 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2423 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2424 /* calc SAV bit */
2425 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2428 static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
2430 TCGv temp = tcg_temp_new_i32();
2431 TCGv result = tcg_temp_new_i32();
2433 tcg_gen_sub_tl(result, r1, r2);
2434 tcg_gen_sub_tl(temp, r2, r1);
2435 tcg_gen_movcond_tl(TCG_COND_GT, result, r1, r2, result, temp);
2437 /* calc V bit */
2438 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
2439 tcg_gen_xor_tl(temp, result, r2);
2440 tcg_gen_movcond_tl(TCG_COND_GT, cpu_PSW_V, r1, r2, cpu_PSW_V, temp);
2441 tcg_gen_xor_tl(temp, r1, r2);
2442 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
2443 /* calc SV bit */
2444 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2445 /* Calc AV bit */
2446 tcg_gen_add_tl(cpu_PSW_AV, result, result);
2447 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
2448 /* calc SAV bit */
2449 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2450 /* write back result */
2451 tcg_gen_mov_tl(ret, result);
2453 tcg_temp_free(temp);
2454 tcg_temp_free(result);
2457 static inline void gen_absdifi(TCGv ret, TCGv r1, int32_t con)
2459 TCGv temp = tcg_const_i32(con);
2460 gen_absdif(ret, r1, temp);
2461 tcg_temp_free(temp);
2464 static inline void gen_absdifsi(TCGv ret, TCGv r1, int32_t con)
2466 TCGv temp = tcg_const_i32(con);
2467 gen_helper_absdif_ssov(ret, cpu_env, r1, temp);
2468 tcg_temp_free(temp);
2471 static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
2473 TCGv high = tcg_temp_new();
2474 TCGv low = tcg_temp_new();
2476 tcg_gen_muls2_tl(low, high, r1, r2);
2477 tcg_gen_mov_tl(ret, low);
2478 /* calc V bit */
2479 tcg_gen_sari_tl(low, low, 31);
2480 tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
2481 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2482 /* calc SV bit */
2483 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2484 /* Calc AV bit */
2485 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2486 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2487 /* calc SAV bit */
2488 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2490 tcg_temp_free(high);
2491 tcg_temp_free(low);
2494 static inline void gen_muli_i32s(TCGv ret, TCGv r1, int32_t con)
2496 TCGv temp = tcg_const_i32(con);
2497 gen_mul_i32s(ret, r1, temp);
2498 tcg_temp_free(temp);
2501 static inline void gen_mul_i64s(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
2503 tcg_gen_muls2_tl(ret_low, ret_high, r1, r2);
2504 /* clear V bit */
2505 tcg_gen_movi_tl(cpu_PSW_V, 0);
2506 /* calc SV bit */
2507 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2508 /* Calc AV bit */
2509 tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
2510 tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2511 /* calc SAV bit */
2512 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2515 static inline void gen_muli_i64s(TCGv ret_low, TCGv ret_high, TCGv r1,
2516 int32_t con)
2518 TCGv temp = tcg_const_i32(con);
2519 gen_mul_i64s(ret_low, ret_high, r1, temp);
2520 tcg_temp_free(temp);
2523 static inline void gen_mul_i64u(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
2525 tcg_gen_mulu2_tl(ret_low, ret_high, r1, r2);
2526 /* clear V bit */
2527 tcg_gen_movi_tl(cpu_PSW_V, 0);
2528 /* calc SV bit */
2529 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2530 /* Calc AV bit */
2531 tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
2532 tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2533 /* calc SAV bit */
2534 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2537 static inline void gen_muli_i64u(TCGv ret_low, TCGv ret_high, TCGv r1,
2538 int32_t con)
2540 TCGv temp = tcg_const_i32(con);
2541 gen_mul_i64u(ret_low, ret_high, r1, temp);
2542 tcg_temp_free(temp);
2545 static inline void gen_mulsi_i32(TCGv ret, TCGv r1, int32_t con)
2547 TCGv temp = tcg_const_i32(con);
2548 gen_helper_mul_ssov(ret, cpu_env, r1, temp);
2549 tcg_temp_free(temp);
2552 static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
2554 TCGv temp = tcg_const_i32(con);
2555 gen_helper_mul_suov(ret, cpu_env, r1, temp);
2556 tcg_temp_free(temp);
2558 /* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
2559 static inline void gen_maddsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2561 TCGv temp = tcg_const_i32(con);
2562 gen_helper_madd32_ssov(ret, cpu_env, r1, r2, temp);
2563 tcg_temp_free(temp);
2566 static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2568 TCGv temp = tcg_const_i32(con);
2569 gen_helper_madd32_suov(ret, cpu_env, r1, r2, temp);
2570 tcg_temp_free(temp);
2573 static void
2574 gen_mul_q(TCGv rl, TCGv rh, TCGv arg1, TCGv arg2, uint32_t n, uint32_t up_shift)
2576 TCGv temp = tcg_temp_new();
2577 TCGv_i64 temp_64 = tcg_temp_new_i64();
2578 TCGv_i64 temp2_64 = tcg_temp_new_i64();
2580 if (n == 0) {
2581 if (up_shift == 32) {
2582 tcg_gen_muls2_tl(rh, rl, arg1, arg2);
2583 } else if (up_shift == 16) {
2584 tcg_gen_ext_i32_i64(temp_64, arg1);
2585 tcg_gen_ext_i32_i64(temp2_64, arg2);
2587 tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2588 tcg_gen_shri_i64(temp_64, temp_64, up_shift);
2589 tcg_gen_extr_i64_i32(rl, rh, temp_64);
2590 } else {
2591 tcg_gen_muls2_tl(rl, rh, arg1, arg2);
2593 /* reset v bit */
2594 tcg_gen_movi_tl(cpu_PSW_V, 0);
2595 } else { /* n is expected to be 1 */
2596 tcg_gen_ext_i32_i64(temp_64, arg1);
2597 tcg_gen_ext_i32_i64(temp2_64, arg2);
2599 tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2601 if (up_shift == 0) {
2602 tcg_gen_shli_i64(temp_64, temp_64, 1);
2603 } else {
2604 tcg_gen_shri_i64(temp_64, temp_64, up_shift - 1);
2606 tcg_gen_extr_i64_i32(rl, rh, temp_64);
2607 /* overflow only occurs if r1 = r2 = 0x8000 */
2608 if (up_shift == 0) {/* result is 64 bit */
2609 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rh,
2610 0x80000000);
2611 } else { /* result is 32 bit */
2612 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rl,
2613 0x80000000);
2615 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2616 /* calc sv overflow bit */
2617 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2619 /* calc av overflow bit */
2620 if (up_shift == 0) {
2621 tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
2622 tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
2623 } else {
2624 tcg_gen_add_tl(cpu_PSW_AV, rl, rl);
2625 tcg_gen_xor_tl(cpu_PSW_AV, rl, cpu_PSW_AV);
2627 /* calc sav overflow bit */
2628 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2629 tcg_temp_free(temp);
2630 tcg_temp_free_i64(temp_64);
2631 tcg_temp_free_i64(temp2_64);
2634 static void
2635 gen_mul_q_16(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
2637 TCGv temp = tcg_temp_new();
2638 if (n == 0) {
2639 tcg_gen_mul_tl(ret, arg1, arg2);
2640 } else { /* n is expected to be 1 */
2641 tcg_gen_mul_tl(ret, arg1, arg2);
2642 tcg_gen_shli_tl(ret, ret, 1);
2643 /* catch special case r1 = r2 = 0x8000 */
2644 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80000000);
2645 tcg_gen_sub_tl(ret, ret, temp);
2647 /* reset v bit */
2648 tcg_gen_movi_tl(cpu_PSW_V, 0);
2649 /* calc av overflow bit */
2650 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2651 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2652 /* calc sav overflow bit */
2653 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2655 tcg_temp_free(temp);
2658 static void gen_mulr_q(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
2660 TCGv temp = tcg_temp_new();
2661 if (n == 0) {
2662 tcg_gen_mul_tl(ret, arg1, arg2);
2663 tcg_gen_addi_tl(ret, ret, 0x8000);
2664 } else {
2665 tcg_gen_mul_tl(ret, arg1, arg2);
2666 tcg_gen_shli_tl(ret, ret, 1);
2667 tcg_gen_addi_tl(ret, ret, 0x8000);
2668 /* catch special case r1 = r2 = 0x8000 */
2669 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80008000);
2670 tcg_gen_muli_tl(temp, temp, 0x8001);
2671 tcg_gen_sub_tl(ret, ret, temp);
2673 /* reset v bit */
2674 tcg_gen_movi_tl(cpu_PSW_V, 0);
2675 /* calc av overflow bit */
2676 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2677 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2678 /* calc sav overflow bit */
2679 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2680 /* cut halfword off */
2681 tcg_gen_andi_tl(ret, ret, 0xffff0000);
2683 tcg_temp_free(temp);
2686 static inline void
2687 gen_madds_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2688 TCGv r3)
2690 TCGv_i64 temp64 = tcg_temp_new_i64();
2691 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2692 gen_helper_madd64_ssov(temp64, cpu_env, r1, temp64, r3);
2693 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2694 tcg_temp_free_i64(temp64);
2697 static inline void
2698 gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2699 int32_t con)
2701 TCGv temp = tcg_const_i32(con);
2702 gen_madds_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2703 tcg_temp_free(temp);
2706 static inline void
2707 gen_maddsu_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2708 TCGv r3)
2710 TCGv_i64 temp64 = tcg_temp_new_i64();
2711 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2712 gen_helper_madd64_suov(temp64, cpu_env, r1, temp64, r3);
2713 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2714 tcg_temp_free_i64(temp64);
2717 static inline void
2718 gen_maddsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2719 int32_t con)
2721 TCGv temp = tcg_const_i32(con);
2722 gen_maddsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2723 tcg_temp_free(temp);
2726 static inline void gen_msubsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2728 TCGv temp = tcg_const_i32(con);
2729 gen_helper_msub32_ssov(ret, cpu_env, r1, r2, temp);
2730 tcg_temp_free(temp);
2733 static inline void gen_msubsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2735 TCGv temp = tcg_const_i32(con);
2736 gen_helper_msub32_suov(ret, cpu_env, r1, r2, temp);
2737 tcg_temp_free(temp);
2740 static inline void
2741 gen_msubs_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2742 TCGv r3)
2744 TCGv_i64 temp64 = tcg_temp_new_i64();
2745 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2746 gen_helper_msub64_ssov(temp64, cpu_env, r1, temp64, r3);
2747 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2748 tcg_temp_free_i64(temp64);
2751 static inline void
2752 gen_msubsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2753 int32_t con)
2755 TCGv temp = tcg_const_i32(con);
2756 gen_msubs_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2757 tcg_temp_free(temp);
2760 static inline void
2761 gen_msubsu_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2762 TCGv r3)
2764 TCGv_i64 temp64 = tcg_temp_new_i64();
2765 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2766 gen_helper_msub64_suov(temp64, cpu_env, r1, temp64, r3);
2767 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2768 tcg_temp_free_i64(temp64);
2771 static inline void
2772 gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2773 int32_t con)
2775 TCGv temp = tcg_const_i32(con);
2776 gen_msubsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2777 tcg_temp_free(temp);
2780 static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
2782 TCGv sat_neg = tcg_const_i32(low);
2783 TCGv temp = tcg_const_i32(up);
2785 /* sat_neg = (arg < low ) ? low : arg; */
2786 tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
2788 /* ret = (sat_neg > up ) ? up : sat_neg; */
2789 tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
2791 tcg_temp_free(sat_neg);
2792 tcg_temp_free(temp);
2795 static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
2797 TCGv temp = tcg_const_i32(up);
2798 /* sat_neg = (arg > up ) ? up : arg; */
2799 tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
2800 tcg_temp_free(temp);
2803 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
2805 if (shift_count == -32) {
2806 tcg_gen_movi_tl(ret, 0);
2807 } else if (shift_count >= 0) {
2808 tcg_gen_shli_tl(ret, r1, shift_count);
2809 } else {
2810 tcg_gen_shri_tl(ret, r1, -shift_count);
2814 static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
2816 TCGv temp_low, temp_high;
2818 if (shiftcount == -16) {
2819 tcg_gen_movi_tl(ret, 0);
2820 } else {
2821 temp_high = tcg_temp_new();
2822 temp_low = tcg_temp_new();
2824 tcg_gen_andi_tl(temp_low, r1, 0xffff);
2825 tcg_gen_andi_tl(temp_high, r1, 0xffff0000);
2826 gen_shi(temp_low, temp_low, shiftcount);
2827 gen_shi(ret, temp_high, shiftcount);
2828 tcg_gen_deposit_tl(ret, ret, temp_low, 0, 16);
2830 tcg_temp_free(temp_low);
2831 tcg_temp_free(temp_high);
2835 static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
2837 uint32_t msk, msk_start;
2838 TCGv temp = tcg_temp_new();
2839 TCGv temp2 = tcg_temp_new();
2840 TCGv t_0 = tcg_const_i32(0);
2842 if (shift_count == 0) {
2843 /* Clear PSW.C and PSW.V */
2844 tcg_gen_movi_tl(cpu_PSW_C, 0);
2845 tcg_gen_mov_tl(cpu_PSW_V, cpu_PSW_C);
2846 tcg_gen_mov_tl(ret, r1);
2847 } else if (shift_count == -32) {
2848 /* set PSW.C */
2849 tcg_gen_mov_tl(cpu_PSW_C, r1);
2850 /* fill ret completely with sign bit */
2851 tcg_gen_sari_tl(ret, r1, 31);
2852 /* clear PSW.V */
2853 tcg_gen_movi_tl(cpu_PSW_V, 0);
2854 } else if (shift_count > 0) {
2855 TCGv t_max = tcg_const_i32(0x7FFFFFFF >> shift_count);
2856 TCGv t_min = tcg_const_i32(((int32_t) -0x80000000) >> shift_count);
2858 /* calc carry */
2859 msk_start = 32 - shift_count;
2860 msk = ((1 << shift_count) - 1) << msk_start;
2861 tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
2862 /* calc v/sv bits */
2863 tcg_gen_setcond_tl(TCG_COND_GT, temp, r1, t_max);
2864 tcg_gen_setcond_tl(TCG_COND_LT, temp2, r1, t_min);
2865 tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
2866 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2867 /* calc sv */
2868 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_V, cpu_PSW_SV);
2869 /* do shift */
2870 tcg_gen_shli_tl(ret, r1, shift_count);
2872 tcg_temp_free(t_max);
2873 tcg_temp_free(t_min);
2874 } else {
2875 /* clear PSW.V */
2876 tcg_gen_movi_tl(cpu_PSW_V, 0);
2877 /* calc carry */
2878 msk = (1 << -shift_count) - 1;
2879 tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
2880 /* do shift */
2881 tcg_gen_sari_tl(ret, r1, -shift_count);
2883 /* calc av overflow bit */
2884 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2885 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2886 /* calc sav overflow bit */
2887 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2889 tcg_temp_free(temp);
2890 tcg_temp_free(temp2);
2891 tcg_temp_free(t_0);
2894 static void gen_shas(TCGv ret, TCGv r1, TCGv r2)
2896 gen_helper_sha_ssov(ret, cpu_env, r1, r2);
2899 static void gen_shasi(TCGv ret, TCGv r1, int32_t con)
2901 TCGv temp = tcg_const_i32(con);
2902 gen_shas(ret, r1, temp);
2903 tcg_temp_free(temp);
2906 static void gen_sha_hi(TCGv ret, TCGv r1, int32_t shift_count)
2908 TCGv low, high;
2910 if (shift_count == 0) {
2911 tcg_gen_mov_tl(ret, r1);
2912 } else if (shift_count > 0) {
2913 low = tcg_temp_new();
2914 high = tcg_temp_new();
2916 tcg_gen_andi_tl(high, r1, 0xffff0000);
2917 tcg_gen_shli_tl(low, r1, shift_count);
2918 tcg_gen_shli_tl(ret, high, shift_count);
2919 tcg_gen_deposit_tl(ret, ret, low, 0, 16);
2921 tcg_temp_free(low);
2922 tcg_temp_free(high);
2923 } else {
2924 low = tcg_temp_new();
2925 high = tcg_temp_new();
2927 tcg_gen_ext16s_tl(low, r1);
2928 tcg_gen_sari_tl(low, low, -shift_count);
2929 tcg_gen_sari_tl(ret, r1, -shift_count);
2930 tcg_gen_deposit_tl(ret, ret, low, 0, 16);
2932 tcg_temp_free(low);
2933 tcg_temp_free(high);
2938 /* ret = {ret[30:0], (r1 cond r2)}; */
2939 static void gen_sh_cond(int cond, TCGv ret, TCGv r1, TCGv r2)
2941 TCGv temp = tcg_temp_new();
2942 TCGv temp2 = tcg_temp_new();
2944 tcg_gen_shli_tl(temp, ret, 1);
2945 tcg_gen_setcond_tl(cond, temp2, r1, r2);
2946 tcg_gen_or_tl(ret, temp, temp2);
2948 tcg_temp_free(temp);
2949 tcg_temp_free(temp2);
2952 static void gen_sh_condi(int cond, TCGv ret, TCGv r1, int32_t con)
2954 TCGv temp = tcg_const_i32(con);
2955 gen_sh_cond(cond, ret, r1, temp);
2956 tcg_temp_free(temp);
2959 static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
2961 gen_helper_add_ssov(ret, cpu_env, r1, r2);
2964 static inline void gen_addsi(TCGv ret, TCGv r1, int32_t con)
2966 TCGv temp = tcg_const_i32(con);
2967 gen_helper_add_ssov(ret, cpu_env, r1, temp);
2968 tcg_temp_free(temp);
2971 static inline void gen_addsui(TCGv ret, TCGv r1, int32_t con)
2973 TCGv temp = tcg_const_i32(con);
2974 gen_helper_add_suov(ret, cpu_env, r1, temp);
2975 tcg_temp_free(temp);
2978 static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
2980 gen_helper_sub_ssov(ret, cpu_env, r1, r2);
2983 static inline void gen_subsu(TCGv ret, TCGv r1, TCGv r2)
2985 gen_helper_sub_suov(ret, cpu_env, r1, r2);
2988 static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2,
2989 int pos1, int pos2,
2990 void(*op1)(TCGv, TCGv, TCGv),
2991 void(*op2)(TCGv, TCGv, TCGv))
2993 TCGv temp1, temp2;
2995 temp1 = tcg_temp_new();
2996 temp2 = tcg_temp_new();
2998 tcg_gen_shri_tl(temp2, r2, pos2);
2999 tcg_gen_shri_tl(temp1, r1, pos1);
3001 (*op1)(temp1, temp1, temp2);
3002 (*op2)(temp1 , ret, temp1);
3004 tcg_gen_deposit_tl(ret, ret, temp1, 0, 1);
3006 tcg_temp_free(temp1);
3007 tcg_temp_free(temp2);
3010 /* ret = r1[pos1] op1 r2[pos2]; */
3011 static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
3012 int pos1, int pos2,
3013 void(*op1)(TCGv, TCGv, TCGv))
3015 TCGv temp1, temp2;
3017 temp1 = tcg_temp_new();
3018 temp2 = tcg_temp_new();
3020 tcg_gen_shri_tl(temp2, r2, pos2);
3021 tcg_gen_shri_tl(temp1, r1, pos1);
3023 (*op1)(ret, temp1, temp2);
3025 tcg_gen_andi_tl(ret, ret, 0x1);
3027 tcg_temp_free(temp1);
3028 tcg_temp_free(temp2);
3031 static inline void gen_accumulating_cond(int cond, TCGv ret, TCGv r1, TCGv r2,
3032 void(*op)(TCGv, TCGv, TCGv))
3034 TCGv temp = tcg_temp_new();
3035 TCGv temp2 = tcg_temp_new();
3036 /* temp = (arg1 cond arg2 )*/
3037 tcg_gen_setcond_tl(cond, temp, r1, r2);
3038 /* temp2 = ret[0]*/
3039 tcg_gen_andi_tl(temp2, ret, 0x1);
3040 /* temp = temp insn temp2 */
3041 (*op)(temp, temp, temp2);
3042 /* ret = {ret[31:1], temp} */
3043 tcg_gen_deposit_tl(ret, ret, temp, 0, 1);
3045 tcg_temp_free(temp);
3046 tcg_temp_free(temp2);
3049 static inline void
3050 gen_accumulating_condi(int cond, TCGv ret, TCGv r1, int32_t con,
3051 void(*op)(TCGv, TCGv, TCGv))
3053 TCGv temp = tcg_const_i32(con);
3054 gen_accumulating_cond(cond, ret, r1, temp, op);
3055 tcg_temp_free(temp);
3058 /* ret = (r1 cond r2) ? 0xFFFFFFFF ? 0x00000000;*/
3059 static inline void gen_cond_w(TCGCond cond, TCGv ret, TCGv r1, TCGv r2)
3061 tcg_gen_setcond_tl(cond, ret, r1, r2);
3062 tcg_gen_neg_tl(ret, ret);
3065 static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
3067 TCGv b0 = tcg_temp_new();
3068 TCGv b1 = tcg_temp_new();
3069 TCGv b2 = tcg_temp_new();
3070 TCGv b3 = tcg_temp_new();
3072 /* byte 0 */
3073 tcg_gen_andi_tl(b0, r1, 0xff);
3074 tcg_gen_setcondi_tl(TCG_COND_EQ, b0, b0, con & 0xff);
3076 /* byte 1 */
3077 tcg_gen_andi_tl(b1, r1, 0xff00);
3078 tcg_gen_setcondi_tl(TCG_COND_EQ, b1, b1, con & 0xff00);
3080 /* byte 2 */
3081 tcg_gen_andi_tl(b2, r1, 0xff0000);
3082 tcg_gen_setcondi_tl(TCG_COND_EQ, b2, b2, con & 0xff0000);
3084 /* byte 3 */
3085 tcg_gen_andi_tl(b3, r1, 0xff000000);
3086 tcg_gen_setcondi_tl(TCG_COND_EQ, b3, b3, con & 0xff000000);
3088 /* combine them */
3089 tcg_gen_or_tl(ret, b0, b1);
3090 tcg_gen_or_tl(ret, ret, b2);
3091 tcg_gen_or_tl(ret, ret, b3);
3093 tcg_temp_free(b0);
3094 tcg_temp_free(b1);
3095 tcg_temp_free(b2);
3096 tcg_temp_free(b3);
3099 static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
3101 TCGv h0 = tcg_temp_new();
3102 TCGv h1 = tcg_temp_new();
3104 /* halfword 0 */
3105 tcg_gen_andi_tl(h0, r1, 0xffff);
3106 tcg_gen_setcondi_tl(TCG_COND_EQ, h0, h0, con & 0xffff);
3108 /* halfword 1 */
3109 tcg_gen_andi_tl(h1, r1, 0xffff0000);
3110 tcg_gen_setcondi_tl(TCG_COND_EQ, h1, h1, con & 0xffff0000);
3112 /* combine them */
3113 tcg_gen_or_tl(ret, h0, h1);
3115 tcg_temp_free(h0);
3116 tcg_temp_free(h1);
3118 /* mask = ((1 << width) -1) << pos;
3119 ret = (r1 & ~mask) | (r2 << pos) & mask); */
3120 static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
3122 TCGv mask = tcg_temp_new();
3123 TCGv temp = tcg_temp_new();
3124 TCGv temp2 = tcg_temp_new();
3126 tcg_gen_movi_tl(mask, 1);
3127 tcg_gen_shl_tl(mask, mask, width);
3128 tcg_gen_subi_tl(mask, mask, 1);
3129 tcg_gen_shl_tl(mask, mask, pos);
3131 tcg_gen_shl_tl(temp, r2, pos);
3132 tcg_gen_and_tl(temp, temp, mask);
3133 tcg_gen_andc_tl(temp2, r1, mask);
3134 tcg_gen_or_tl(ret, temp, temp2);
3136 tcg_temp_free(mask);
3137 tcg_temp_free(temp);
3138 tcg_temp_free(temp2);
3141 static inline void gen_bsplit(TCGv rl, TCGv rh, TCGv r1)
3143 TCGv_i64 temp = tcg_temp_new_i64();
3145 gen_helper_bsplit(temp, r1);
3146 tcg_gen_extr_i64_i32(rl, rh, temp);
3148 tcg_temp_free_i64(temp);
3151 static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1)
3153 TCGv_i64 temp = tcg_temp_new_i64();
3155 gen_helper_unpack(temp, r1);
3156 tcg_gen_extr_i64_i32(rl, rh, temp);
3158 tcg_temp_free_i64(temp);
3161 static inline void
3162 gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
3164 TCGv_i64 ret = tcg_temp_new_i64();
3166 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
3167 gen_helper_dvinit_b_13(ret, cpu_env, r1, r2);
3168 } else {
3169 gen_helper_dvinit_b_131(ret, cpu_env, r1, r2);
3171 tcg_gen_extr_i64_i32(rl, rh, ret);
3173 tcg_temp_free_i64(ret);
3176 static inline void
3177 gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
3179 TCGv_i64 ret = tcg_temp_new_i64();
3181 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
3182 gen_helper_dvinit_h_13(ret, cpu_env, r1, r2);
3183 } else {
3184 gen_helper_dvinit_h_131(ret, cpu_env, r1, r2);
3186 tcg_gen_extr_i64_i32(rl, rh, ret);
3188 tcg_temp_free_i64(ret);
3191 static void gen_calc_usb_mul_h(TCGv arg_low, TCGv arg_high)
3193 TCGv temp = tcg_temp_new();
3194 /* calc AV bit */
3195 tcg_gen_add_tl(temp, arg_low, arg_low);
3196 tcg_gen_xor_tl(temp, temp, arg_low);
3197 tcg_gen_add_tl(cpu_PSW_AV, arg_high, arg_high);
3198 tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, arg_high);
3199 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
3200 /* calc SAV bit */
3201 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3202 tcg_gen_movi_tl(cpu_PSW_V, 0);
3203 tcg_temp_free(temp);
3206 static void gen_calc_usb_mulr_h(TCGv arg)
3208 TCGv temp = tcg_temp_new();
3209 /* calc AV bit */
3210 tcg_gen_add_tl(temp, arg, arg);
3211 tcg_gen_xor_tl(temp, temp, arg);
3212 tcg_gen_shli_tl(cpu_PSW_AV, temp, 16);
3213 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
3214 /* calc SAV bit */
3215 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3216 /* clear V bit */
3217 tcg_gen_movi_tl(cpu_PSW_V, 0);
3218 tcg_temp_free(temp);
3221 /* helpers for generating program flow micro-ops */
3223 static inline void gen_save_pc(target_ulong pc)
3225 tcg_gen_movi_tl(cpu_PC, pc);
3228 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
3230 if (unlikely(ctx->base.singlestep_enabled)) {
3231 return false;
3234 #ifndef CONFIG_USER_ONLY
3235 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3236 #else
3237 return true;
3238 #endif
3241 static void generate_qemu_excp(DisasContext *ctx, int excp)
3243 TCGv_i32 tmp = tcg_const_i32(excp);
3244 gen_helper_qemu_excp(cpu_env, tmp);
3245 ctx->base.is_jmp = DISAS_NORETURN;
3246 tcg_temp_free(tmp);
3249 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3251 if (use_goto_tb(ctx, dest)) {
3252 tcg_gen_goto_tb(n);
3253 gen_save_pc(dest);
3254 tcg_gen_exit_tb(ctx->base.tb, n);
3255 } else {
3256 gen_save_pc(dest);
3257 if (ctx->base.singlestep_enabled) {
3258 generate_qemu_excp(ctx, EXCP_DEBUG);
3260 tcg_gen_exit_tb(NULL, 0);
3264 static void generate_trap(DisasContext *ctx, int class, int tin)
3266 TCGv_i32 classtemp = tcg_const_i32(class);
3267 TCGv_i32 tintemp = tcg_const_i32(tin);
3269 gen_save_pc(ctx->base.pc_next);
3270 gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp);
3271 ctx->base.is_jmp = DISAS_NORETURN;
3273 tcg_temp_free(classtemp);
3274 tcg_temp_free(tintemp);
3277 static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
3278 TCGv r2, int16_t address)
3280 TCGLabel *jumpLabel = gen_new_label();
3281 tcg_gen_brcond_tl(cond, r1, r2, jumpLabel);
3283 gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
3285 gen_set_label(jumpLabel);
3286 gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2);
3289 static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1,
3290 int r2, int16_t address)
3292 TCGv temp = tcg_const_i32(r2);
3293 gen_branch_cond(ctx, cond, r1, temp, address);
3294 tcg_temp_free(temp);
3297 static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
3299 TCGLabel *l1 = gen_new_label();
3301 tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
3302 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
3303 gen_goto_tb(ctx, 1, ctx->base.pc_next + offset);
3304 gen_set_label(l1);
3305 gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
3308 static void gen_fcall_save_ctx(DisasContext *ctx)
3310 TCGv temp = tcg_temp_new();
3312 tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
3313 tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
3314 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3315 tcg_gen_mov_tl(cpu_gpr_a[10], temp);
3317 tcg_temp_free(temp);
3320 static void gen_fret(DisasContext *ctx)
3322 TCGv temp = tcg_temp_new();
3324 tcg_gen_andi_tl(temp, cpu_gpr_a[11], ~0x1);
3325 tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
3326 tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
3327 tcg_gen_mov_tl(cpu_PC, temp);
3328 tcg_gen_exit_tb(NULL, 0);
3329 ctx->base.is_jmp = DISAS_NORETURN;
3331 tcg_temp_free(temp);
3334 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
3335 int r2 , int32_t constant , int32_t offset)
3337 TCGv temp, temp2;
3338 int n;
3340 switch (opc) {
3341 /* SB-format jumps */
3342 case OPC1_16_SB_J:
3343 case OPC1_32_B_J:
3344 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3345 break;
3346 case OPC1_32_B_CALL:
3347 case OPC1_16_SB_CALL:
3348 gen_helper_1arg(call, ctx->pc_succ_insn);
3349 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3350 break;
3351 case OPC1_16_SB_JZ:
3352 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
3353 break;
3354 case OPC1_16_SB_JNZ:
3355 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
3356 break;
3357 /* SBC-format jumps */
3358 case OPC1_16_SBC_JEQ:
3359 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
3360 break;
3361 case OPC1_16_SBC_JEQ2:
3362 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant,
3363 offset + 16);
3364 break;
3365 case OPC1_16_SBC_JNE:
3366 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
3367 break;
3368 case OPC1_16_SBC_JNE2:
3369 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15],
3370 constant, offset + 16);
3371 break;
3372 /* SBRN-format jumps */
3373 case OPC1_16_SBRN_JZ_T:
3374 temp = tcg_temp_new();
3375 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
3376 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3377 tcg_temp_free(temp);
3378 break;
3379 case OPC1_16_SBRN_JNZ_T:
3380 temp = tcg_temp_new();
3381 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
3382 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3383 tcg_temp_free(temp);
3384 break;
3385 /* SBR-format jumps */
3386 case OPC1_16_SBR_JEQ:
3387 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
3388 offset);
3389 break;
3390 case OPC1_16_SBR_JEQ2:
3391 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
3392 offset + 16);
3393 break;
3394 case OPC1_16_SBR_JNE:
3395 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
3396 offset);
3397 break;
3398 case OPC1_16_SBR_JNE2:
3399 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
3400 offset + 16);
3401 break;
3402 case OPC1_16_SBR_JNZ:
3403 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
3404 break;
3405 case OPC1_16_SBR_JNZ_A:
3406 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3407 break;
3408 case OPC1_16_SBR_JGEZ:
3409 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
3410 break;
3411 case OPC1_16_SBR_JGTZ:
3412 gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
3413 break;
3414 case OPC1_16_SBR_JLEZ:
3415 gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
3416 break;
3417 case OPC1_16_SBR_JLTZ:
3418 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
3419 break;
3420 case OPC1_16_SBR_JZ:
3421 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
3422 break;
3423 case OPC1_16_SBR_JZ_A:
3424 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3425 break;
3426 case OPC1_16_SBR_LOOP:
3427 gen_loop(ctx, r1, offset * 2 - 32);
3428 break;
3429 /* SR-format jumps */
3430 case OPC1_16_SR_JI:
3431 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
3432 tcg_gen_exit_tb(NULL, 0);
3433 break;
3434 case OPC2_32_SYS_RET:
3435 case OPC2_16_SR_RET:
3436 gen_helper_ret(cpu_env);
3437 tcg_gen_exit_tb(NULL, 0);
3438 break;
3439 /* B-format */
3440 case OPC1_32_B_CALLA:
3441 gen_helper_1arg(call, ctx->pc_succ_insn);
3442 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3443 break;
3444 case OPC1_32_B_FCALL:
3445 gen_fcall_save_ctx(ctx);
3446 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3447 break;
3448 case OPC1_32_B_FCALLA:
3449 gen_fcall_save_ctx(ctx);
3450 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3451 break;
3452 case OPC1_32_B_JLA:
3453 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3454 /* fall through */
3455 case OPC1_32_B_JA:
3456 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3457 break;
3458 case OPC1_32_B_JL:
3459 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3460 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3461 break;
3462 /* BOL format */
3463 case OPCM_32_BRC_EQ_NEQ:
3464 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
3465 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
3466 } else {
3467 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
3469 break;
3470 case OPCM_32_BRC_GE:
3471 if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
3472 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
3473 } else {
3474 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3475 gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
3476 offset);
3478 break;
3479 case OPCM_32_BRC_JLT:
3480 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
3481 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
3482 } else {
3483 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3484 gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
3485 offset);
3487 break;
3488 case OPCM_32_BRC_JNE:
3489 temp = tcg_temp_new();
3490 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
3491 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3492 /* subi is unconditional */
3493 tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3494 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3495 } else {
3496 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3497 /* addi is unconditional */
3498 tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3499 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3501 tcg_temp_free(temp);
3502 break;
3503 /* BRN format */
3504 case OPCM_32_BRN_JTT:
3505 n = MASK_OP_BRN_N(ctx->opcode);
3507 temp = tcg_temp_new();
3508 tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << n));
3510 if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
3511 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3512 } else {
3513 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3515 tcg_temp_free(temp);
3516 break;
3517 /* BRR Format */
3518 case OPCM_32_BRR_EQ_NEQ:
3519 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
3520 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
3521 offset);
3522 } else {
3523 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3524 offset);
3526 break;
3527 case OPCM_32_BRR_ADDR_EQ_NEQ:
3528 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
3529 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
3530 offset);
3531 } else {
3532 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
3533 offset);
3535 break;
3536 case OPCM_32_BRR_GE:
3537 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
3538 gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3539 offset);
3540 } else {
3541 gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3542 offset);
3544 break;
3545 case OPCM_32_BRR_JLT:
3546 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
3547 gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
3548 offset);
3549 } else {
3550 gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3551 offset);
3553 break;
3554 case OPCM_32_BRR_LOOP:
3555 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
3556 gen_loop(ctx, r2, offset * 2);
3557 } else {
3558 /* OPC2_32_BRR_LOOPU */
3559 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3561 break;
3562 case OPCM_32_BRR_JNE:
3563 temp = tcg_temp_new();
3564 temp2 = tcg_temp_new();
3565 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
3566 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3567 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3568 tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3569 /* subi is unconditional */
3570 tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3571 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3572 } else {
3573 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3574 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3575 tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3576 /* addi is unconditional */
3577 tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3578 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3580 tcg_temp_free(temp);
3581 tcg_temp_free(temp2);
3582 break;
3583 case OPCM_32_BRR_JNZ:
3584 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
3585 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3586 } else {
3587 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3589 break;
3590 default:
3591 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3593 ctx->base.is_jmp = DISAS_NORETURN;
3598 * Functions for decoding instructions
3601 static void decode_src_opc(DisasContext *ctx, int op1)
3603 int r1;
3604 int32_t const4;
3605 TCGv temp, temp2;
3607 r1 = MASK_OP_SRC_S1D(ctx->opcode);
3608 const4 = MASK_OP_SRC_CONST4_SEXT(ctx->opcode);
3610 switch (op1) {
3611 case OPC1_16_SRC_ADD:
3612 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3613 break;
3614 case OPC1_16_SRC_ADD_A15:
3615 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[15], const4);
3616 break;
3617 case OPC1_16_SRC_ADD_15A:
3618 gen_addi_d(cpu_gpr_d[15], cpu_gpr_d[r1], const4);
3619 break;
3620 case OPC1_16_SRC_ADD_A:
3621 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], const4);
3622 break;
3623 case OPC1_16_SRC_CADD:
3624 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3625 cpu_gpr_d[15]);
3626 break;
3627 case OPC1_16_SRC_CADDN:
3628 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3629 cpu_gpr_d[15]);
3630 break;
3631 case OPC1_16_SRC_CMOV:
3632 temp = tcg_const_tl(0);
3633 temp2 = tcg_const_tl(const4);
3634 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3635 temp2, cpu_gpr_d[r1]);
3636 tcg_temp_free(temp);
3637 tcg_temp_free(temp2);
3638 break;
3639 case OPC1_16_SRC_CMOVN:
3640 temp = tcg_const_tl(0);
3641 temp2 = tcg_const_tl(const4);
3642 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3643 temp2, cpu_gpr_d[r1]);
3644 tcg_temp_free(temp);
3645 tcg_temp_free(temp2);
3646 break;
3647 case OPC1_16_SRC_EQ:
3648 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3649 const4);
3650 break;
3651 case OPC1_16_SRC_LT:
3652 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3653 const4);
3654 break;
3655 case OPC1_16_SRC_MOV:
3656 tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3657 break;
3658 case OPC1_16_SRC_MOV_A:
3659 const4 = MASK_OP_SRC_CONST4(ctx->opcode);
3660 tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
3661 break;
3662 case OPC1_16_SRC_MOV_E:
3663 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3664 tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3665 tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
3666 } else {
3667 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3669 break;
3670 case OPC1_16_SRC_SH:
3671 gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3672 break;
3673 case OPC1_16_SRC_SHA:
3674 gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3675 break;
3676 default:
3677 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3681 static void decode_srr_opc(DisasContext *ctx, int op1)
3683 int r1, r2;
3684 TCGv temp;
3686 r1 = MASK_OP_SRR_S1D(ctx->opcode);
3687 r2 = MASK_OP_SRR_S2(ctx->opcode);
3689 switch (op1) {
3690 case OPC1_16_SRR_ADD:
3691 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3692 break;
3693 case OPC1_16_SRR_ADD_A15:
3694 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3695 break;
3696 case OPC1_16_SRR_ADD_15A:
3697 gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3698 break;
3699 case OPC1_16_SRR_ADD_A:
3700 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
3701 break;
3702 case OPC1_16_SRR_ADDS:
3703 gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3704 break;
3705 case OPC1_16_SRR_AND:
3706 tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3707 break;
3708 case OPC1_16_SRR_CMOV:
3709 temp = tcg_const_tl(0);
3710 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3711 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3712 tcg_temp_free(temp);
3713 break;
3714 case OPC1_16_SRR_CMOVN:
3715 temp = tcg_const_tl(0);
3716 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3717 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3718 tcg_temp_free(temp);
3719 break;
3720 case OPC1_16_SRR_EQ:
3721 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3722 cpu_gpr_d[r2]);
3723 break;
3724 case OPC1_16_SRR_LT:
3725 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3726 cpu_gpr_d[r2]);
3727 break;
3728 case OPC1_16_SRR_MOV:
3729 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]);
3730 break;
3731 case OPC1_16_SRR_MOV_A:
3732 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]);
3733 break;
3734 case OPC1_16_SRR_MOV_AA:
3735 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_a[r2]);
3736 break;
3737 case OPC1_16_SRR_MOV_D:
3738 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]);
3739 break;
3740 case OPC1_16_SRR_MUL:
3741 gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3742 break;
3743 case OPC1_16_SRR_OR:
3744 tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3745 break;
3746 case OPC1_16_SRR_SUB:
3747 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3748 break;
3749 case OPC1_16_SRR_SUB_A15B:
3750 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3751 break;
3752 case OPC1_16_SRR_SUB_15AB:
3753 gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3754 break;
3755 case OPC1_16_SRR_SUBS:
3756 gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3757 break;
3758 case OPC1_16_SRR_XOR:
3759 tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3760 break;
3761 default:
3762 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3766 static void decode_ssr_opc(DisasContext *ctx, int op1)
3768 int r1, r2;
3770 r1 = MASK_OP_SSR_S1(ctx->opcode);
3771 r2 = MASK_OP_SSR_S2(ctx->opcode);
3773 switch (op1) {
3774 case OPC1_16_SSR_ST_A:
3775 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3776 break;
3777 case OPC1_16_SSR_ST_A_POSTINC:
3778 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3779 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3780 break;
3781 case OPC1_16_SSR_ST_B:
3782 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3783 break;
3784 case OPC1_16_SSR_ST_B_POSTINC:
3785 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3786 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3787 break;
3788 case OPC1_16_SSR_ST_H:
3789 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3790 break;
3791 case OPC1_16_SSR_ST_H_POSTINC:
3792 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3793 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3794 break;
3795 case OPC1_16_SSR_ST_W:
3796 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3797 break;
3798 case OPC1_16_SSR_ST_W_POSTINC:
3799 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3800 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3801 break;
3802 default:
3803 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3807 static void decode_sc_opc(DisasContext *ctx, int op1)
3809 int32_t const16;
3811 const16 = MASK_OP_SC_CONST8(ctx->opcode);
3813 switch (op1) {
3814 case OPC1_16_SC_AND:
3815 tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3816 break;
3817 case OPC1_16_SC_BISR:
3818 gen_helper_1arg(bisr, const16 & 0xff);
3819 break;
3820 case OPC1_16_SC_LD_A:
3821 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3822 break;
3823 case OPC1_16_SC_LD_W:
3824 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3825 break;
3826 case OPC1_16_SC_MOV:
3827 tcg_gen_movi_tl(cpu_gpr_d[15], const16);
3828 break;
3829 case OPC1_16_SC_OR:
3830 tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3831 break;
3832 case OPC1_16_SC_ST_A:
3833 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3834 break;
3835 case OPC1_16_SC_ST_W:
3836 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3837 break;
3838 case OPC1_16_SC_SUB_A:
3839 tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
3840 break;
3841 default:
3842 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3846 static void decode_slr_opc(DisasContext *ctx, int op1)
3848 int r1, r2;
3850 r1 = MASK_OP_SLR_D(ctx->opcode);
3851 r2 = MASK_OP_SLR_S2(ctx->opcode);
3853 switch (op1) {
3854 /* SLR-format */
3855 case OPC1_16_SLR_LD_A:
3856 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3857 break;
3858 case OPC1_16_SLR_LD_A_POSTINC:
3859 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3860 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3861 break;
3862 case OPC1_16_SLR_LD_BU:
3863 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3864 break;
3865 case OPC1_16_SLR_LD_BU_POSTINC:
3866 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3867 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3868 break;
3869 case OPC1_16_SLR_LD_H:
3870 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3871 break;
3872 case OPC1_16_SLR_LD_H_POSTINC:
3873 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3874 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3875 break;
3876 case OPC1_16_SLR_LD_W:
3877 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3878 break;
3879 case OPC1_16_SLR_LD_W_POSTINC:
3880 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3881 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3882 break;
3883 default:
3884 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3888 static void decode_sro_opc(DisasContext *ctx, int op1)
3890 int r2;
3891 int32_t address;
3893 r2 = MASK_OP_SRO_S2(ctx->opcode);
3894 address = MASK_OP_SRO_OFF4(ctx->opcode);
3896 /* SRO-format */
3897 switch (op1) {
3898 case OPC1_16_SRO_LD_A:
3899 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3900 break;
3901 case OPC1_16_SRO_LD_BU:
3902 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3903 break;
3904 case OPC1_16_SRO_LD_H:
3905 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
3906 break;
3907 case OPC1_16_SRO_LD_W:
3908 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3909 break;
3910 case OPC1_16_SRO_ST_A:
3911 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3912 break;
3913 case OPC1_16_SRO_ST_B:
3914 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3915 break;
3916 case OPC1_16_SRO_ST_H:
3917 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3918 break;
3919 case OPC1_16_SRO_ST_W:
3920 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3921 break;
3922 default:
3923 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3927 static void decode_sr_system(DisasContext *ctx)
3929 uint32_t op2;
3930 op2 = MASK_OP_SR_OP2(ctx->opcode);
3932 switch (op2) {
3933 case OPC2_16_SR_NOP:
3934 break;
3935 case OPC2_16_SR_RET:
3936 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
3937 break;
3938 case OPC2_16_SR_RFE:
3939 gen_helper_rfe(cpu_env);
3940 tcg_gen_exit_tb(NULL, 0);
3941 ctx->base.is_jmp = DISAS_NORETURN;
3942 break;
3943 case OPC2_16_SR_DEBUG:
3944 /* raise EXCP_DEBUG */
3945 break;
3946 case OPC2_16_SR_FRET:
3947 gen_fret(ctx);
3948 break;
3949 default:
3950 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3954 static void decode_sr_accu(DisasContext *ctx)
3956 uint32_t op2;
3957 uint32_t r1;
3958 TCGv temp;
3960 r1 = MASK_OP_SR_S1D(ctx->opcode);
3961 op2 = MASK_OP_SR_OP2(ctx->opcode);
3963 switch (op2) {
3964 case OPC2_16_SR_RSUB:
3965 /* overflow only if r1 = -0x80000000 */
3966 temp = tcg_const_i32(-0x80000000);
3967 /* calc V bit */
3968 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r1], temp);
3969 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
3970 /* calc SV bit */
3971 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
3972 /* sub */
3973 tcg_gen_neg_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3974 /* calc av */
3975 tcg_gen_add_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_gpr_d[r1]);
3976 tcg_gen_xor_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_PSW_AV);
3977 /* calc sav */
3978 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3979 tcg_temp_free(temp);
3980 break;
3981 case OPC2_16_SR_SAT_B:
3982 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
3983 break;
3984 case OPC2_16_SR_SAT_BU:
3985 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
3986 break;
3987 case OPC2_16_SR_SAT_H:
3988 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
3989 break;
3990 case OPC2_16_SR_SAT_HU:
3991 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
3992 break;
3993 default:
3994 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3998 static void decode_16Bit_opc(DisasContext *ctx)
4000 int op1;
4001 int r1, r2;
4002 int32_t const16;
4003 int32_t address;
4004 TCGv temp;
4006 op1 = MASK_OP_MAJOR(ctx->opcode);
4008 /* handle ADDSC.A opcode only being 6 bit long */
4009 if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
4010 op1 = OPC1_16_SRRS_ADDSC_A;
4013 switch (op1) {
4014 case OPC1_16_SRC_ADD:
4015 case OPC1_16_SRC_ADD_A15:
4016 case OPC1_16_SRC_ADD_15A:
4017 case OPC1_16_SRC_ADD_A:
4018 case OPC1_16_SRC_CADD:
4019 case OPC1_16_SRC_CADDN:
4020 case OPC1_16_SRC_CMOV:
4021 case OPC1_16_SRC_CMOVN:
4022 case OPC1_16_SRC_EQ:
4023 case OPC1_16_SRC_LT:
4024 case OPC1_16_SRC_MOV:
4025 case OPC1_16_SRC_MOV_A:
4026 case OPC1_16_SRC_MOV_E:
4027 case OPC1_16_SRC_SH:
4028 case OPC1_16_SRC_SHA:
4029 decode_src_opc(ctx, op1);
4030 break;
4031 /* SRR-format */
4032 case OPC1_16_SRR_ADD:
4033 case OPC1_16_SRR_ADD_A15:
4034 case OPC1_16_SRR_ADD_15A:
4035 case OPC1_16_SRR_ADD_A:
4036 case OPC1_16_SRR_ADDS:
4037 case OPC1_16_SRR_AND:
4038 case OPC1_16_SRR_CMOV:
4039 case OPC1_16_SRR_CMOVN:
4040 case OPC1_16_SRR_EQ:
4041 case OPC1_16_SRR_LT:
4042 case OPC1_16_SRR_MOV:
4043 case OPC1_16_SRR_MOV_A:
4044 case OPC1_16_SRR_MOV_AA:
4045 case OPC1_16_SRR_MOV_D:
4046 case OPC1_16_SRR_MUL:
4047 case OPC1_16_SRR_OR:
4048 case OPC1_16_SRR_SUB:
4049 case OPC1_16_SRR_SUB_A15B:
4050 case OPC1_16_SRR_SUB_15AB:
4051 case OPC1_16_SRR_SUBS:
4052 case OPC1_16_SRR_XOR:
4053 decode_srr_opc(ctx, op1);
4054 break;
4055 /* SSR-format */
4056 case OPC1_16_SSR_ST_A:
4057 case OPC1_16_SSR_ST_A_POSTINC:
4058 case OPC1_16_SSR_ST_B:
4059 case OPC1_16_SSR_ST_B_POSTINC:
4060 case OPC1_16_SSR_ST_H:
4061 case OPC1_16_SSR_ST_H_POSTINC:
4062 case OPC1_16_SSR_ST_W:
4063 case OPC1_16_SSR_ST_W_POSTINC:
4064 decode_ssr_opc(ctx, op1);
4065 break;
4066 /* SRRS-format */
4067 case OPC1_16_SRRS_ADDSC_A:
4068 r2 = MASK_OP_SRRS_S2(ctx->opcode);
4069 r1 = MASK_OP_SRRS_S1D(ctx->opcode);
4070 const16 = MASK_OP_SRRS_N(ctx->opcode);
4071 temp = tcg_temp_new();
4072 tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
4073 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
4074 tcg_temp_free(temp);
4075 break;
4076 /* SLRO-format */
4077 case OPC1_16_SLRO_LD_A:
4078 r1 = MASK_OP_SLRO_D(ctx->opcode);
4079 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4080 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4081 break;
4082 case OPC1_16_SLRO_LD_BU:
4083 r1 = MASK_OP_SLRO_D(ctx->opcode);
4084 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4085 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
4086 break;
4087 case OPC1_16_SLRO_LD_H:
4088 r1 = MASK_OP_SLRO_D(ctx->opcode);
4089 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4090 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
4091 break;
4092 case OPC1_16_SLRO_LD_W:
4093 r1 = MASK_OP_SLRO_D(ctx->opcode);
4094 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4095 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4096 break;
4097 /* SB-format */
4098 case OPC1_16_SB_CALL:
4099 case OPC1_16_SB_J:
4100 case OPC1_16_SB_JNZ:
4101 case OPC1_16_SB_JZ:
4102 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
4103 gen_compute_branch(ctx, op1, 0, 0, 0, address);
4104 break;
4105 /* SBC-format */
4106 case OPC1_16_SBC_JEQ:
4107 case OPC1_16_SBC_JNE:
4108 address = MASK_OP_SBC_DISP4(ctx->opcode);
4109 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
4110 gen_compute_branch(ctx, op1, 0, 0, const16, address);
4111 break;
4112 case OPC1_16_SBC_JEQ2:
4113 case OPC1_16_SBC_JNE2:
4114 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4115 address = MASK_OP_SBC_DISP4(ctx->opcode);
4116 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
4117 gen_compute_branch(ctx, op1, 0, 0, const16, address);
4118 } else {
4119 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4121 break;
4122 /* SBRN-format */
4123 case OPC1_16_SBRN_JNZ_T:
4124 case OPC1_16_SBRN_JZ_T:
4125 address = MASK_OP_SBRN_DISP4(ctx->opcode);
4126 const16 = MASK_OP_SBRN_N(ctx->opcode);
4127 gen_compute_branch(ctx, op1, 0, 0, const16, address);
4128 break;
4129 /* SBR-format */
4130 case OPC1_16_SBR_JEQ2:
4131 case OPC1_16_SBR_JNE2:
4132 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4133 r1 = MASK_OP_SBR_S2(ctx->opcode);
4134 address = MASK_OP_SBR_DISP4(ctx->opcode);
4135 gen_compute_branch(ctx, op1, r1, 0, 0, address);
4136 } else {
4137 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4139 break;
4140 case OPC1_16_SBR_JEQ:
4141 case OPC1_16_SBR_JGEZ:
4142 case OPC1_16_SBR_JGTZ:
4143 case OPC1_16_SBR_JLEZ:
4144 case OPC1_16_SBR_JLTZ:
4145 case OPC1_16_SBR_JNE:
4146 case OPC1_16_SBR_JNZ:
4147 case OPC1_16_SBR_JNZ_A:
4148 case OPC1_16_SBR_JZ:
4149 case OPC1_16_SBR_JZ_A:
4150 case OPC1_16_SBR_LOOP:
4151 r1 = MASK_OP_SBR_S2(ctx->opcode);
4152 address = MASK_OP_SBR_DISP4(ctx->opcode);
4153 gen_compute_branch(ctx, op1, r1, 0, 0, address);
4154 break;
4155 /* SC-format */
4156 case OPC1_16_SC_AND:
4157 case OPC1_16_SC_BISR:
4158 case OPC1_16_SC_LD_A:
4159 case OPC1_16_SC_LD_W:
4160 case OPC1_16_SC_MOV:
4161 case OPC1_16_SC_OR:
4162 case OPC1_16_SC_ST_A:
4163 case OPC1_16_SC_ST_W:
4164 case OPC1_16_SC_SUB_A:
4165 decode_sc_opc(ctx, op1);
4166 break;
4167 /* SLR-format */
4168 case OPC1_16_SLR_LD_A:
4169 case OPC1_16_SLR_LD_A_POSTINC:
4170 case OPC1_16_SLR_LD_BU:
4171 case OPC1_16_SLR_LD_BU_POSTINC:
4172 case OPC1_16_SLR_LD_H:
4173 case OPC1_16_SLR_LD_H_POSTINC:
4174 case OPC1_16_SLR_LD_W:
4175 case OPC1_16_SLR_LD_W_POSTINC:
4176 decode_slr_opc(ctx, op1);
4177 break;
4178 /* SRO-format */
4179 case OPC1_16_SRO_LD_A:
4180 case OPC1_16_SRO_LD_BU:
4181 case OPC1_16_SRO_LD_H:
4182 case OPC1_16_SRO_LD_W:
4183 case OPC1_16_SRO_ST_A:
4184 case OPC1_16_SRO_ST_B:
4185 case OPC1_16_SRO_ST_H:
4186 case OPC1_16_SRO_ST_W:
4187 decode_sro_opc(ctx, op1);
4188 break;
4189 /* SSRO-format */
4190 case OPC1_16_SSRO_ST_A:
4191 r1 = MASK_OP_SSRO_S1(ctx->opcode);
4192 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4193 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4194 break;
4195 case OPC1_16_SSRO_ST_B:
4196 r1 = MASK_OP_SSRO_S1(ctx->opcode);
4197 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4198 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
4199 break;
4200 case OPC1_16_SSRO_ST_H:
4201 r1 = MASK_OP_SSRO_S1(ctx->opcode);
4202 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4203 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
4204 break;
4205 case OPC1_16_SSRO_ST_W:
4206 r1 = MASK_OP_SSRO_S1(ctx->opcode);
4207 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4208 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4209 break;
4210 /* SR-format */
4211 case OPCM_16_SR_SYSTEM:
4212 decode_sr_system(ctx);
4213 break;
4214 case OPCM_16_SR_ACCU:
4215 decode_sr_accu(ctx);
4216 break;
4217 case OPC1_16_SR_JI:
4218 r1 = MASK_OP_SR_S1D(ctx->opcode);
4219 gen_compute_branch(ctx, op1, r1, 0, 0, 0);
4220 break;
4221 case OPC1_16_SR_NOT:
4222 r1 = MASK_OP_SR_S1D(ctx->opcode);
4223 tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
4224 break;
4225 default:
4226 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4231 * 32 bit instructions
4234 /* ABS-format */
4235 static void decode_abs_ldw(DisasContext *ctx)
4237 int32_t op2;
4238 int32_t r1;
4239 uint32_t address;
4240 TCGv temp;
4242 r1 = MASK_OP_ABS_S1D(ctx->opcode);
4243 address = MASK_OP_ABS_OFF18(ctx->opcode);
4244 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4246 temp = tcg_const_i32(EA_ABS_FORMAT(address));
4248 switch (op2) {
4249 case OPC2_32_ABS_LD_A:
4250 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
4251 break;
4252 case OPC2_32_ABS_LD_D:
4253 CHECK_REG_PAIR(r1);
4254 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4255 break;
4256 case OPC2_32_ABS_LD_DA:
4257 CHECK_REG_PAIR(r1);
4258 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4259 break;
4260 case OPC2_32_ABS_LD_W:
4261 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
4262 break;
4263 default:
4264 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4267 tcg_temp_free(temp);
4270 static void decode_abs_ldb(DisasContext *ctx)
4272 int32_t op2;
4273 int32_t r1;
4274 uint32_t address;
4275 TCGv temp;
4277 r1 = MASK_OP_ABS_S1D(ctx->opcode);
4278 address = MASK_OP_ABS_OFF18(ctx->opcode);
4279 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4281 temp = tcg_const_i32(EA_ABS_FORMAT(address));
4283 switch (op2) {
4284 case OPC2_32_ABS_LD_B:
4285 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB);
4286 break;
4287 case OPC2_32_ABS_LD_BU:
4288 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
4289 break;
4290 case OPC2_32_ABS_LD_H:
4291 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW);
4292 break;
4293 case OPC2_32_ABS_LD_HU:
4294 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
4295 break;
4296 default:
4297 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4300 tcg_temp_free(temp);
4303 static void decode_abs_ldst_swap(DisasContext *ctx)
4305 int32_t op2;
4306 int32_t r1;
4307 uint32_t address;
4308 TCGv temp;
4310 r1 = MASK_OP_ABS_S1D(ctx->opcode);
4311 address = MASK_OP_ABS_OFF18(ctx->opcode);
4312 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4314 temp = tcg_const_i32(EA_ABS_FORMAT(address));
4316 switch (op2) {
4317 case OPC2_32_ABS_LDMST:
4318 gen_ldmst(ctx, r1, temp);
4319 break;
4320 case OPC2_32_ABS_SWAP_W:
4321 gen_swap(ctx, r1, temp);
4322 break;
4323 default:
4324 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4327 tcg_temp_free(temp);
4330 static void decode_abs_ldst_context(DisasContext *ctx)
4332 uint32_t op2;
4333 int32_t off18;
4335 off18 = MASK_OP_ABS_OFF18(ctx->opcode);
4336 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4338 switch (op2) {
4339 case OPC2_32_ABS_LDLCX:
4340 gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18));
4341 break;
4342 case OPC2_32_ABS_LDUCX:
4343 gen_helper_1arg(lducx, EA_ABS_FORMAT(off18));
4344 break;
4345 case OPC2_32_ABS_STLCX:
4346 gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18));
4347 break;
4348 case OPC2_32_ABS_STUCX:
4349 gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
4350 break;
4351 default:
4352 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4356 static void decode_abs_store(DisasContext *ctx)
4358 int32_t op2;
4359 int32_t r1;
4360 uint32_t address;
4361 TCGv temp;
4363 r1 = MASK_OP_ABS_S1D(ctx->opcode);
4364 address = MASK_OP_ABS_OFF18(ctx->opcode);
4365 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4367 temp = tcg_const_i32(EA_ABS_FORMAT(address));
4369 switch (op2) {
4370 case OPC2_32_ABS_ST_A:
4371 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
4372 break;
4373 case OPC2_32_ABS_ST_D:
4374 CHECK_REG_PAIR(r1);
4375 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4376 break;
4377 case OPC2_32_ABS_ST_DA:
4378 CHECK_REG_PAIR(r1);
4379 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4380 break;
4381 case OPC2_32_ABS_ST_W:
4382 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
4383 break;
4384 default:
4385 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4387 tcg_temp_free(temp);
4390 static void decode_abs_storeb_h(DisasContext *ctx)
4392 int32_t op2;
4393 int32_t r1;
4394 uint32_t address;
4395 TCGv temp;
4397 r1 = MASK_OP_ABS_S1D(ctx->opcode);
4398 address = MASK_OP_ABS_OFF18(ctx->opcode);
4399 op2 = MASK_OP_ABS_OP2(ctx->opcode);
4401 temp = tcg_const_i32(EA_ABS_FORMAT(address));
4403 switch (op2) {
4404 case OPC2_32_ABS_ST_B:
4405 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
4406 break;
4407 case OPC2_32_ABS_ST_H:
4408 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
4409 break;
4410 default:
4411 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4413 tcg_temp_free(temp);
4416 /* Bit-format */
4418 static void decode_bit_andacc(DisasContext *ctx)
4420 uint32_t op2;
4421 int r1, r2, r3;
4422 int pos1, pos2;
4424 r1 = MASK_OP_BIT_S1(ctx->opcode);
4425 r2 = MASK_OP_BIT_S2(ctx->opcode);
4426 r3 = MASK_OP_BIT_D(ctx->opcode);
4427 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4428 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4429 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4432 switch (op2) {
4433 case OPC2_32_BIT_AND_AND_T:
4434 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4435 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
4436 break;
4437 case OPC2_32_BIT_AND_ANDN_T:
4438 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4439 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
4440 break;
4441 case OPC2_32_BIT_AND_NOR_T:
4442 if (TCG_TARGET_HAS_andc_i32) {
4443 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4444 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
4445 } else {
4446 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4447 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
4449 break;
4450 case OPC2_32_BIT_AND_OR_T:
4451 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4452 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
4453 break;
4454 default:
4455 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4459 static void decode_bit_logical_t(DisasContext *ctx)
4461 uint32_t op2;
4462 int r1, r2, r3;
4463 int pos1, pos2;
4464 r1 = MASK_OP_BIT_S1(ctx->opcode);
4465 r2 = MASK_OP_BIT_S2(ctx->opcode);
4466 r3 = MASK_OP_BIT_D(ctx->opcode);
4467 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4468 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4469 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4471 switch (op2) {
4472 case OPC2_32_BIT_AND_T:
4473 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4474 pos1, pos2, &tcg_gen_and_tl);
4475 break;
4476 case OPC2_32_BIT_ANDN_T:
4477 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4478 pos1, pos2, &tcg_gen_andc_tl);
4479 break;
4480 case OPC2_32_BIT_NOR_T:
4481 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4482 pos1, pos2, &tcg_gen_nor_tl);
4483 break;
4484 case OPC2_32_BIT_OR_T:
4485 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4486 pos1, pos2, &tcg_gen_or_tl);
4487 break;
4488 default:
4489 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4493 static void decode_bit_insert(DisasContext *ctx)
4495 uint32_t op2;
4496 int r1, r2, r3;
4497 int pos1, pos2;
4498 TCGv temp;
4499 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4500 r1 = MASK_OP_BIT_S1(ctx->opcode);
4501 r2 = MASK_OP_BIT_S2(ctx->opcode);
4502 r3 = MASK_OP_BIT_D(ctx->opcode);
4503 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4504 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4506 temp = tcg_temp_new();
4508 tcg_gen_shri_tl(temp, cpu_gpr_d[r2], pos2);
4509 if (op2 == OPC2_32_BIT_INSN_T) {
4510 tcg_gen_not_tl(temp, temp);
4512 tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, pos1, 1);
4513 tcg_temp_free(temp);
4516 static void decode_bit_logical_t2(DisasContext *ctx)
4518 uint32_t op2;
4520 int r1, r2, r3;
4521 int pos1, pos2;
4523 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4524 r1 = MASK_OP_BIT_S1(ctx->opcode);
4525 r2 = MASK_OP_BIT_S2(ctx->opcode);
4526 r3 = MASK_OP_BIT_D(ctx->opcode);
4527 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4528 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4530 switch (op2) {
4531 case OPC2_32_BIT_NAND_T:
4532 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4533 pos1, pos2, &tcg_gen_nand_tl);
4534 break;
4535 case OPC2_32_BIT_ORN_T:
4536 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4537 pos1, pos2, &tcg_gen_orc_tl);
4538 break;
4539 case OPC2_32_BIT_XNOR_T:
4540 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4541 pos1, pos2, &tcg_gen_eqv_tl);
4542 break;
4543 case OPC2_32_BIT_XOR_T:
4544 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4545 pos1, pos2, &tcg_gen_xor_tl);
4546 break;
4547 default:
4548 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4552 static void decode_bit_orand(DisasContext *ctx)
4554 uint32_t op2;
4556 int r1, r2, r3;
4557 int pos1, pos2;
4559 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4560 r1 = MASK_OP_BIT_S1(ctx->opcode);
4561 r2 = MASK_OP_BIT_S2(ctx->opcode);
4562 r3 = MASK_OP_BIT_D(ctx->opcode);
4563 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4564 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4566 switch (op2) {
4567 case OPC2_32_BIT_OR_AND_T:
4568 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4569 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl);
4570 break;
4571 case OPC2_32_BIT_OR_ANDN_T:
4572 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4573 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
4574 break;
4575 case OPC2_32_BIT_OR_NOR_T:
4576 if (TCG_TARGET_HAS_orc_i32) {
4577 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4578 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
4579 } else {
4580 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4581 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_or_tl);
4583 break;
4584 case OPC2_32_BIT_OR_OR_T:
4585 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4586 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
4587 break;
4588 default:
4589 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4593 static void decode_bit_sh_logic1(DisasContext *ctx)
4595 uint32_t op2;
4596 int r1, r2, r3;
4597 int pos1, pos2;
4598 TCGv temp;
4600 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4601 r1 = MASK_OP_BIT_S1(ctx->opcode);
4602 r2 = MASK_OP_BIT_S2(ctx->opcode);
4603 r3 = MASK_OP_BIT_D(ctx->opcode);
4604 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4605 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4607 temp = tcg_temp_new();
4609 switch (op2) {
4610 case OPC2_32_BIT_SH_AND_T:
4611 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4612 pos1, pos2, &tcg_gen_and_tl);
4613 break;
4614 case OPC2_32_BIT_SH_ANDN_T:
4615 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4616 pos1, pos2, &tcg_gen_andc_tl);
4617 break;
4618 case OPC2_32_BIT_SH_NOR_T:
4619 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4620 pos1, pos2, &tcg_gen_nor_tl);
4621 break;
4622 case OPC2_32_BIT_SH_OR_T:
4623 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4624 pos1, pos2, &tcg_gen_or_tl);
4625 break;
4626 default:
4627 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4629 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4630 tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4631 tcg_temp_free(temp);
4634 static void decode_bit_sh_logic2(DisasContext *ctx)
4636 uint32_t op2;
4637 int r1, r2, r3;
4638 int pos1, pos2;
4639 TCGv temp;
4641 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4642 r1 = MASK_OP_BIT_S1(ctx->opcode);
4643 r2 = MASK_OP_BIT_S2(ctx->opcode);
4644 r3 = MASK_OP_BIT_D(ctx->opcode);
4645 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4646 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4648 temp = tcg_temp_new();
4650 switch (op2) {
4651 case OPC2_32_BIT_SH_NAND_T:
4652 gen_bit_1op(temp, cpu_gpr_d[r1] , cpu_gpr_d[r2] ,
4653 pos1, pos2, &tcg_gen_nand_tl);
4654 break;
4655 case OPC2_32_BIT_SH_ORN_T:
4656 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4657 pos1, pos2, &tcg_gen_orc_tl);
4658 break;
4659 case OPC2_32_BIT_SH_XNOR_T:
4660 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4661 pos1, pos2, &tcg_gen_eqv_tl);
4662 break;
4663 case OPC2_32_BIT_SH_XOR_T:
4664 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4665 pos1, pos2, &tcg_gen_xor_tl);
4666 break;
4667 default:
4668 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4670 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4671 tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4672 tcg_temp_free(temp);
4675 /* BO-format */
4678 static void decode_bo_addrmode_post_pre_base(DisasContext *ctx)
4680 uint32_t op2;
4681 uint32_t off10;
4682 int32_t r1, r2;
4683 TCGv temp;
4685 r1 = MASK_OP_BO_S1D(ctx->opcode);
4686 r2 = MASK_OP_BO_S2(ctx->opcode);
4687 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4688 op2 = MASK_OP_BO_OP2(ctx->opcode);
4690 switch (op2) {
4691 case OPC2_32_BO_CACHEA_WI_SHORTOFF:
4692 case OPC2_32_BO_CACHEA_W_SHORTOFF:
4693 case OPC2_32_BO_CACHEA_I_SHORTOFF:
4694 /* instruction to access the cache */
4695 break;
4696 case OPC2_32_BO_CACHEA_WI_POSTINC:
4697 case OPC2_32_BO_CACHEA_W_POSTINC:
4698 case OPC2_32_BO_CACHEA_I_POSTINC:
4699 /* instruction to access the cache, but we still need to handle
4700 the addressing mode */
4701 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4702 break;
4703 case OPC2_32_BO_CACHEA_WI_PREINC:
4704 case OPC2_32_BO_CACHEA_W_PREINC:
4705 case OPC2_32_BO_CACHEA_I_PREINC:
4706 /* instruction to access the cache, but we still need to handle
4707 the addressing mode */
4708 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4709 break;
4710 case OPC2_32_BO_CACHEI_WI_SHORTOFF:
4711 case OPC2_32_BO_CACHEI_W_SHORTOFF:
4712 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
4713 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4715 break;
4716 case OPC2_32_BO_CACHEI_W_POSTINC:
4717 case OPC2_32_BO_CACHEI_WI_POSTINC:
4718 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4719 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4720 } else {
4721 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4723 break;
4724 case OPC2_32_BO_CACHEI_W_PREINC:
4725 case OPC2_32_BO_CACHEI_WI_PREINC:
4726 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4727 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4728 } else {
4729 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4731 break;
4732 case OPC2_32_BO_ST_A_SHORTOFF:
4733 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4734 break;
4735 case OPC2_32_BO_ST_A_POSTINC:
4736 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4737 MO_LESL);
4738 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4739 break;
4740 case OPC2_32_BO_ST_A_PREINC:
4741 gen_st_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4742 break;
4743 case OPC2_32_BO_ST_B_SHORTOFF:
4744 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4745 break;
4746 case OPC2_32_BO_ST_B_POSTINC:
4747 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4748 MO_UB);
4749 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4750 break;
4751 case OPC2_32_BO_ST_B_PREINC:
4752 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4753 break;
4754 case OPC2_32_BO_ST_D_SHORTOFF:
4755 CHECK_REG_PAIR(r1);
4756 gen_offset_st_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4757 off10, ctx);
4758 break;
4759 case OPC2_32_BO_ST_D_POSTINC:
4760 CHECK_REG_PAIR(r1);
4761 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
4762 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4763 break;
4764 case OPC2_32_BO_ST_D_PREINC:
4765 CHECK_REG_PAIR(r1);
4766 temp = tcg_temp_new();
4767 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4768 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4769 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4770 tcg_temp_free(temp);
4771 break;
4772 case OPC2_32_BO_ST_DA_SHORTOFF:
4773 CHECK_REG_PAIR(r1);
4774 gen_offset_st_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4775 off10, ctx);
4776 break;
4777 case OPC2_32_BO_ST_DA_POSTINC:
4778 CHECK_REG_PAIR(r1);
4779 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
4780 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4781 break;
4782 case OPC2_32_BO_ST_DA_PREINC:
4783 CHECK_REG_PAIR(r1);
4784 temp = tcg_temp_new();
4785 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4786 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4787 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4788 tcg_temp_free(temp);
4789 break;
4790 case OPC2_32_BO_ST_H_SHORTOFF:
4791 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4792 break;
4793 case OPC2_32_BO_ST_H_POSTINC:
4794 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4795 MO_LEUW);
4796 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4797 break;
4798 case OPC2_32_BO_ST_H_PREINC:
4799 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4800 break;
4801 case OPC2_32_BO_ST_Q_SHORTOFF:
4802 temp = tcg_temp_new();
4803 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4804 gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4805 tcg_temp_free(temp);
4806 break;
4807 case OPC2_32_BO_ST_Q_POSTINC:
4808 temp = tcg_temp_new();
4809 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4810 tcg_gen_qemu_st_tl(temp, cpu_gpr_a[r2], ctx->mem_idx,
4811 MO_LEUW);
4812 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4813 tcg_temp_free(temp);
4814 break;
4815 case OPC2_32_BO_ST_Q_PREINC:
4816 temp = tcg_temp_new();
4817 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4818 gen_st_preincr(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4819 tcg_temp_free(temp);
4820 break;
4821 case OPC2_32_BO_ST_W_SHORTOFF:
4822 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4823 break;
4824 case OPC2_32_BO_ST_W_POSTINC:
4825 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4826 MO_LEUL);
4827 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4828 break;
4829 case OPC2_32_BO_ST_W_PREINC:
4830 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4831 break;
4832 default:
4833 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4837 static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx)
4839 uint32_t op2;
4840 uint32_t off10;
4841 int32_t r1, r2;
4842 TCGv temp, temp2, temp3;
4844 r1 = MASK_OP_BO_S1D(ctx->opcode);
4845 r2 = MASK_OP_BO_S2(ctx->opcode);
4846 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4847 op2 = MASK_OP_BO_OP2(ctx->opcode);
4849 temp = tcg_temp_new();
4850 temp2 = tcg_temp_new();
4851 temp3 = tcg_const_i32(off10);
4852 CHECK_REG_PAIR(r2);
4853 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
4854 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4856 switch (op2) {
4857 case OPC2_32_BO_CACHEA_WI_BR:
4858 case OPC2_32_BO_CACHEA_W_BR:
4859 case OPC2_32_BO_CACHEA_I_BR:
4860 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4861 break;
4862 case OPC2_32_BO_CACHEA_WI_CIRC:
4863 case OPC2_32_BO_CACHEA_W_CIRC:
4864 case OPC2_32_BO_CACHEA_I_CIRC:
4865 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4866 break;
4867 case OPC2_32_BO_ST_A_BR:
4868 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4869 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4870 break;
4871 case OPC2_32_BO_ST_A_CIRC:
4872 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4873 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4874 break;
4875 case OPC2_32_BO_ST_B_BR:
4876 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4877 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4878 break;
4879 case OPC2_32_BO_ST_B_CIRC:
4880 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4881 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4882 break;
4883 case OPC2_32_BO_ST_D_BR:
4884 CHECK_REG_PAIR(r1);
4885 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
4886 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4887 break;
4888 case OPC2_32_BO_ST_D_CIRC:
4889 CHECK_REG_PAIR(r1);
4890 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4891 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4892 tcg_gen_addi_tl(temp, temp, 4);
4893 tcg_gen_rem_tl(temp, temp, temp2);
4894 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4895 tcg_gen_qemu_st_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4896 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4897 break;
4898 case OPC2_32_BO_ST_DA_BR:
4899 CHECK_REG_PAIR(r1);
4900 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
4901 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4902 break;
4903 case OPC2_32_BO_ST_DA_CIRC:
4904 CHECK_REG_PAIR(r1);
4905 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4906 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4907 tcg_gen_addi_tl(temp, temp, 4);
4908 tcg_gen_rem_tl(temp, temp, temp2);
4909 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4910 tcg_gen_qemu_st_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4911 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4912 break;
4913 case OPC2_32_BO_ST_H_BR:
4914 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4915 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4916 break;
4917 case OPC2_32_BO_ST_H_CIRC:
4918 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4919 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4920 break;
4921 case OPC2_32_BO_ST_Q_BR:
4922 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4923 tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW);
4924 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4925 break;
4926 case OPC2_32_BO_ST_Q_CIRC:
4927 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4928 tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW);
4929 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4930 break;
4931 case OPC2_32_BO_ST_W_BR:
4932 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4933 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4934 break;
4935 case OPC2_32_BO_ST_W_CIRC:
4936 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4937 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
4938 break;
4939 default:
4940 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4942 tcg_temp_free(temp);
4943 tcg_temp_free(temp2);
4944 tcg_temp_free(temp3);
4947 static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx)
4949 uint32_t op2;
4950 uint32_t off10;
4951 int32_t r1, r2;
4952 TCGv temp;
4954 r1 = MASK_OP_BO_S1D(ctx->opcode);
4955 r2 = MASK_OP_BO_S2(ctx->opcode);
4956 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4957 op2 = MASK_OP_BO_OP2(ctx->opcode);
4959 switch (op2) {
4960 case OPC2_32_BO_LD_A_SHORTOFF:
4961 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4962 break;
4963 case OPC2_32_BO_LD_A_POSTINC:
4964 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4965 MO_LEUL);
4966 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4967 break;
4968 case OPC2_32_BO_LD_A_PREINC:
4969 gen_ld_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4970 break;
4971 case OPC2_32_BO_LD_B_SHORTOFF:
4972 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4973 break;
4974 case OPC2_32_BO_LD_B_POSTINC:
4975 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4976 MO_SB);
4977 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4978 break;
4979 case OPC2_32_BO_LD_B_PREINC:
4980 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4981 break;
4982 case OPC2_32_BO_LD_BU_SHORTOFF:
4983 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4984 break;
4985 case OPC2_32_BO_LD_BU_POSTINC:
4986 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4987 MO_UB);
4988 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4989 break;
4990 case OPC2_32_BO_LD_BU_PREINC:
4991 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4992 break;
4993 case OPC2_32_BO_LD_D_SHORTOFF:
4994 CHECK_REG_PAIR(r1);
4995 gen_offset_ld_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4996 off10, ctx);
4997 break;
4998 case OPC2_32_BO_LD_D_POSTINC:
4999 CHECK_REG_PAIR(r1);
5000 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
5001 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5002 break;
5003 case OPC2_32_BO_LD_D_PREINC:
5004 CHECK_REG_PAIR(r1);
5005 temp = tcg_temp_new();
5006 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5007 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
5008 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
5009 tcg_temp_free(temp);
5010 break;
5011 case OPC2_32_BO_LD_DA_SHORTOFF:
5012 CHECK_REG_PAIR(r1);
5013 gen_offset_ld_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
5014 off10, ctx);
5015 break;
5016 case OPC2_32_BO_LD_DA_POSTINC:
5017 CHECK_REG_PAIR(r1);
5018 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
5019 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5020 break;
5021 case OPC2_32_BO_LD_DA_PREINC:
5022 CHECK_REG_PAIR(r1);
5023 temp = tcg_temp_new();
5024 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5025 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
5026 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
5027 tcg_temp_free(temp);
5028 break;
5029 case OPC2_32_BO_LD_H_SHORTOFF:
5030 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
5031 break;
5032 case OPC2_32_BO_LD_H_POSTINC:
5033 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
5034 MO_LESW);
5035 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5036 break;
5037 case OPC2_32_BO_LD_H_PREINC:
5038 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
5039 break;
5040 case OPC2_32_BO_LD_HU_SHORTOFF:
5041 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
5042 break;
5043 case OPC2_32_BO_LD_HU_POSTINC:
5044 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
5045 MO_LEUW);
5046 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5047 break;
5048 case OPC2_32_BO_LD_HU_PREINC:
5049 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
5050 break;
5051 case OPC2_32_BO_LD_Q_SHORTOFF:
5052 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
5053 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
5054 break;
5055 case OPC2_32_BO_LD_Q_POSTINC:
5056 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
5057 MO_LEUW);
5058 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
5059 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5060 break;
5061 case OPC2_32_BO_LD_Q_PREINC:
5062 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
5063 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
5064 break;
5065 case OPC2_32_BO_LD_W_SHORTOFF:
5066 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
5067 break;
5068 case OPC2_32_BO_LD_W_POSTINC:
5069 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
5070 MO_LEUL);
5071 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5072 break;
5073 case OPC2_32_BO_LD_W_PREINC:
5074 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
5075 break;
5076 default:
5077 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5081 static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx)
5083 uint32_t op2;
5084 uint32_t off10;
5085 int r1, r2;
5087 TCGv temp, temp2, temp3;
5089 r1 = MASK_OP_BO_S1D(ctx->opcode);
5090 r2 = MASK_OP_BO_S2(ctx->opcode);
5091 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
5092 op2 = MASK_OP_BO_OP2(ctx->opcode);
5094 temp = tcg_temp_new();
5095 temp2 = tcg_temp_new();
5096 temp3 = tcg_const_i32(off10);
5097 CHECK_REG_PAIR(r2);
5098 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
5099 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
5102 switch (op2) {
5103 case OPC2_32_BO_LD_A_BR:
5104 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
5105 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5106 break;
5107 case OPC2_32_BO_LD_A_CIRC:
5108 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
5109 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5110 break;
5111 case OPC2_32_BO_LD_B_BR:
5112 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
5113 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5114 break;
5115 case OPC2_32_BO_LD_B_CIRC:
5116 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
5117 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5118 break;
5119 case OPC2_32_BO_LD_BU_BR:
5120 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
5121 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5122 break;
5123 case OPC2_32_BO_LD_BU_CIRC:
5124 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
5125 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5126 break;
5127 case OPC2_32_BO_LD_D_BR:
5128 CHECK_REG_PAIR(r1);
5129 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
5130 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5131 break;
5132 case OPC2_32_BO_LD_D_CIRC:
5133 CHECK_REG_PAIR(r1);
5134 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
5135 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
5136 tcg_gen_addi_tl(temp, temp, 4);
5137 tcg_gen_rem_tl(temp, temp, temp2);
5138 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
5139 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL);
5140 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5141 break;
5142 case OPC2_32_BO_LD_DA_BR:
5143 CHECK_REG_PAIR(r1);
5144 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
5145 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5146 break;
5147 case OPC2_32_BO_LD_DA_CIRC:
5148 CHECK_REG_PAIR(r1);
5149 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
5150 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
5151 tcg_gen_addi_tl(temp, temp, 4);
5152 tcg_gen_rem_tl(temp, temp, temp2);
5153 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
5154 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL);
5155 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5156 break;
5157 case OPC2_32_BO_LD_H_BR:
5158 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
5159 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5160 break;
5161 case OPC2_32_BO_LD_H_CIRC:
5162 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
5163 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5164 break;
5165 case OPC2_32_BO_LD_HU_BR:
5166 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
5167 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5168 break;
5169 case OPC2_32_BO_LD_HU_CIRC:
5170 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
5171 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5172 break;
5173 case OPC2_32_BO_LD_Q_BR:
5174 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
5175 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
5176 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5177 break;
5178 case OPC2_32_BO_LD_Q_CIRC:
5179 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
5180 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
5181 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5182 break;
5183 case OPC2_32_BO_LD_W_BR:
5184 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
5185 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5186 break;
5187 case OPC2_32_BO_LD_W_CIRC:
5188 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
5189 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5190 break;
5191 default:
5192 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5194 tcg_temp_free(temp);
5195 tcg_temp_free(temp2);
5196 tcg_temp_free(temp3);
5199 static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx)
5201 uint32_t op2;
5202 uint32_t off10;
5203 int r1, r2;
5205 TCGv temp, temp2;
5207 r1 = MASK_OP_BO_S1D(ctx->opcode);
5208 r2 = MASK_OP_BO_S2(ctx->opcode);
5209 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
5210 op2 = MASK_OP_BO_OP2(ctx->opcode);
5213 temp = tcg_temp_new();
5214 temp2 = tcg_temp_new();
5216 switch (op2) {
5217 case OPC2_32_BO_LDLCX_SHORTOFF:
5218 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5219 gen_helper_ldlcx(cpu_env, temp);
5220 break;
5221 case OPC2_32_BO_LDMST_SHORTOFF:
5222 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5223 gen_ldmst(ctx, r1, temp);
5224 break;
5225 case OPC2_32_BO_LDMST_POSTINC:
5226 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
5227 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5228 break;
5229 case OPC2_32_BO_LDMST_PREINC:
5230 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5231 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
5232 break;
5233 case OPC2_32_BO_LDUCX_SHORTOFF:
5234 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5235 gen_helper_lducx(cpu_env, temp);
5236 break;
5237 case OPC2_32_BO_LEA_SHORTOFF:
5238 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], off10);
5239 break;
5240 case OPC2_32_BO_STLCX_SHORTOFF:
5241 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5242 gen_helper_stlcx(cpu_env, temp);
5243 break;
5244 case OPC2_32_BO_STUCX_SHORTOFF:
5245 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5246 gen_helper_stucx(cpu_env, temp);
5247 break;
5248 case OPC2_32_BO_SWAP_W_SHORTOFF:
5249 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5250 gen_swap(ctx, r1, temp);
5251 break;
5252 case OPC2_32_BO_SWAP_W_POSTINC:
5253 gen_swap(ctx, r1, cpu_gpr_a[r2]);
5254 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5255 break;
5256 case OPC2_32_BO_SWAP_W_PREINC:
5257 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5258 gen_swap(ctx, r1, cpu_gpr_a[r2]);
5259 break;
5260 case OPC2_32_BO_CMPSWAP_W_SHORTOFF:
5261 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5262 gen_cmpswap(ctx, r1, temp);
5263 break;
5264 case OPC2_32_BO_CMPSWAP_W_POSTINC:
5265 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
5266 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5267 break;
5268 case OPC2_32_BO_CMPSWAP_W_PREINC:
5269 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5270 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
5271 break;
5272 case OPC2_32_BO_SWAPMSK_W_SHORTOFF:
5273 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
5274 gen_swapmsk(ctx, r1, temp);
5275 break;
5276 case OPC2_32_BO_SWAPMSK_W_POSTINC:
5277 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
5278 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5279 break;
5280 case OPC2_32_BO_SWAPMSK_W_PREINC:
5281 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
5282 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
5283 break;
5284 default:
5285 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5287 tcg_temp_free(temp);
5288 tcg_temp_free(temp2);
5291 static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx)
5293 uint32_t op2;
5294 uint32_t off10;
5295 int r1, r2;
5297 TCGv temp, temp2, temp3;
5299 r1 = MASK_OP_BO_S1D(ctx->opcode);
5300 r2 = MASK_OP_BO_S2(ctx->opcode);
5301 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
5302 op2 = MASK_OP_BO_OP2(ctx->opcode);
5304 temp = tcg_temp_new();
5305 temp2 = tcg_temp_new();
5306 temp3 = tcg_const_i32(off10);
5307 CHECK_REG_PAIR(r2);
5308 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
5309 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
5311 switch (op2) {
5312 case OPC2_32_BO_LDMST_BR:
5313 gen_ldmst(ctx, r1, temp2);
5314 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5315 break;
5316 case OPC2_32_BO_LDMST_CIRC:
5317 gen_ldmst(ctx, r1, temp2);
5318 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5319 break;
5320 case OPC2_32_BO_SWAP_W_BR:
5321 gen_swap(ctx, r1, temp2);
5322 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5323 break;
5324 case OPC2_32_BO_SWAP_W_CIRC:
5325 gen_swap(ctx, r1, temp2);
5326 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5327 break;
5328 case OPC2_32_BO_CMPSWAP_W_BR:
5329 gen_cmpswap(ctx, r1, temp2);
5330 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5331 break;
5332 case OPC2_32_BO_CMPSWAP_W_CIRC:
5333 gen_cmpswap(ctx, r1, temp2);
5334 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5335 break;
5336 case OPC2_32_BO_SWAPMSK_W_BR:
5337 gen_swapmsk(ctx, r1, temp2);
5338 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
5339 break;
5340 case OPC2_32_BO_SWAPMSK_W_CIRC:
5341 gen_swapmsk(ctx, r1, temp2);
5342 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
5343 break;
5344 default:
5345 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5348 tcg_temp_free(temp);
5349 tcg_temp_free(temp2);
5350 tcg_temp_free(temp3);
5353 static void decode_bol_opc(DisasContext *ctx, int32_t op1)
5355 int r1, r2;
5356 int32_t address;
5357 TCGv temp;
5359 r1 = MASK_OP_BOL_S1D(ctx->opcode);
5360 r2 = MASK_OP_BOL_S2(ctx->opcode);
5361 address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);
5363 switch (op1) {
5364 case OPC1_32_BOL_LD_A_LONGOFF:
5365 temp = tcg_temp_new();
5366 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
5367 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
5368 tcg_temp_free(temp);
5369 break;
5370 case OPC1_32_BOL_LD_W_LONGOFF:
5371 temp = tcg_temp_new();
5372 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
5373 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
5374 tcg_temp_free(temp);
5375 break;
5376 case OPC1_32_BOL_LEA_LONGOFF:
5377 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
5378 break;
5379 case OPC1_32_BOL_ST_A_LONGOFF:
5380 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5381 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
5382 } else {
5383 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5385 break;
5386 case OPC1_32_BOL_ST_W_LONGOFF:
5387 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
5388 break;
5389 case OPC1_32_BOL_LD_B_LONGOFF:
5390 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5391 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
5392 } else {
5393 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5395 break;
5396 case OPC1_32_BOL_LD_BU_LONGOFF:
5397 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5398 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);
5399 } else {
5400 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5402 break;
5403 case OPC1_32_BOL_LD_H_LONGOFF:
5404 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5405 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
5406 } else {
5407 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5409 break;
5410 case OPC1_32_BOL_LD_HU_LONGOFF:
5411 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5412 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);
5413 } else {
5414 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5416 break;
5417 case OPC1_32_BOL_ST_B_LONGOFF:
5418 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5419 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
5420 } else {
5421 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5423 break;
5424 case OPC1_32_BOL_ST_H_LONGOFF:
5425 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5426 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
5427 } else {
5428 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5430 break;
5431 default:
5432 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5436 /* RC format */
5437 static void decode_rc_logical_shift(DisasContext *ctx)
5439 uint32_t op2;
5440 int r1, r2;
5441 int32_t const9;
5442 TCGv temp;
5444 r2 = MASK_OP_RC_D(ctx->opcode);
5445 r1 = MASK_OP_RC_S1(ctx->opcode);
5446 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5447 op2 = MASK_OP_RC_OP2(ctx->opcode);
5449 temp = tcg_temp_new();
5451 switch (op2) {
5452 case OPC2_32_RC_AND:
5453 tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5454 break;
5455 case OPC2_32_RC_ANDN:
5456 tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
5457 break;
5458 case OPC2_32_RC_NAND:
5459 tcg_gen_movi_tl(temp, const9);
5460 tcg_gen_nand_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
5461 break;
5462 case OPC2_32_RC_NOR:
5463 tcg_gen_movi_tl(temp, const9);
5464 tcg_gen_nor_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
5465 break;
5466 case OPC2_32_RC_OR:
5467 tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5468 break;
5469 case OPC2_32_RC_ORN:
5470 tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
5471 break;
5472 case OPC2_32_RC_SH:
5473 const9 = sextract32(const9, 0, 6);
5474 gen_shi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5475 break;
5476 case OPC2_32_RC_SH_H:
5477 const9 = sextract32(const9, 0, 5);
5478 gen_sh_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5479 break;
5480 case OPC2_32_RC_SHA:
5481 const9 = sextract32(const9, 0, 6);
5482 gen_shaci(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5483 break;
5484 case OPC2_32_RC_SHA_H:
5485 const9 = sextract32(const9, 0, 5);
5486 gen_sha_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5487 break;
5488 case OPC2_32_RC_SHAS:
5489 gen_shasi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5490 break;
5491 case OPC2_32_RC_XNOR:
5492 tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5493 tcg_gen_not_tl(cpu_gpr_d[r2], cpu_gpr_d[r2]);
5494 break;
5495 case OPC2_32_RC_XOR:
5496 tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5497 break;
5498 default:
5499 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5501 tcg_temp_free(temp);
5504 static void decode_rc_accumulator(DisasContext *ctx)
5506 uint32_t op2;
5507 int r1, r2;
5508 int16_t const9;
5510 TCGv temp;
5512 r2 = MASK_OP_RC_D(ctx->opcode);
5513 r1 = MASK_OP_RC_S1(ctx->opcode);
5514 const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
5516 op2 = MASK_OP_RC_OP2(ctx->opcode);
5518 temp = tcg_temp_new();
5520 switch (op2) {
5521 case OPC2_32_RC_ABSDIF:
5522 gen_absdifi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5523 break;
5524 case OPC2_32_RC_ABSDIFS:
5525 gen_absdifsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5526 break;
5527 case OPC2_32_RC_ADD:
5528 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5529 break;
5530 case OPC2_32_RC_ADDC:
5531 gen_addci_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5532 break;
5533 case OPC2_32_RC_ADDS:
5534 gen_addsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5535 break;
5536 case OPC2_32_RC_ADDS_U:
5537 gen_addsui(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5538 break;
5539 case OPC2_32_RC_ADDX:
5540 gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5541 break;
5542 case OPC2_32_RC_AND_EQ:
5543 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5544 const9, &tcg_gen_and_tl);
5545 break;
5546 case OPC2_32_RC_AND_GE:
5547 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5548 const9, &tcg_gen_and_tl);
5549 break;
5550 case OPC2_32_RC_AND_GE_U:
5551 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5552 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5553 const9, &tcg_gen_and_tl);
5554 break;
5555 case OPC2_32_RC_AND_LT:
5556 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5557 const9, &tcg_gen_and_tl);
5558 break;
5559 case OPC2_32_RC_AND_LT_U:
5560 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5561 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5562 const9, &tcg_gen_and_tl);
5563 break;
5564 case OPC2_32_RC_AND_NE:
5565 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5566 const9, &tcg_gen_and_tl);
5567 break;
5568 case OPC2_32_RC_EQ:
5569 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5570 break;
5571 case OPC2_32_RC_EQANY_B:
5572 gen_eqany_bi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5573 break;
5574 case OPC2_32_RC_EQANY_H:
5575 gen_eqany_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5576 break;
5577 case OPC2_32_RC_GE:
5578 tcg_gen_setcondi_tl(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5579 break;
5580 case OPC2_32_RC_GE_U:
5581 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5582 tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5583 break;
5584 case OPC2_32_RC_LT:
5585 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5586 break;
5587 case OPC2_32_RC_LT_U:
5588 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5589 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5590 break;
5591 case OPC2_32_RC_MAX:
5592 tcg_gen_movi_tl(temp, const9);
5593 tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5594 cpu_gpr_d[r1], temp);
5595 break;
5596 case OPC2_32_RC_MAX_U:
5597 tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
5598 tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5599 cpu_gpr_d[r1], temp);
5600 break;
5601 case OPC2_32_RC_MIN:
5602 tcg_gen_movi_tl(temp, const9);
5603 tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5604 cpu_gpr_d[r1], temp);
5605 break;
5606 case OPC2_32_RC_MIN_U:
5607 tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
5608 tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5609 cpu_gpr_d[r1], temp);
5610 break;
5611 case OPC2_32_RC_NE:
5612 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5613 break;
5614 case OPC2_32_RC_OR_EQ:
5615 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5616 const9, &tcg_gen_or_tl);
5617 break;
5618 case OPC2_32_RC_OR_GE:
5619 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5620 const9, &tcg_gen_or_tl);
5621 break;
5622 case OPC2_32_RC_OR_GE_U:
5623 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5624 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5625 const9, &tcg_gen_or_tl);
5626 break;
5627 case OPC2_32_RC_OR_LT:
5628 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5629 const9, &tcg_gen_or_tl);
5630 break;
5631 case OPC2_32_RC_OR_LT_U:
5632 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5633 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5634 const9, &tcg_gen_or_tl);
5635 break;
5636 case OPC2_32_RC_OR_NE:
5637 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5638 const9, &tcg_gen_or_tl);
5639 break;
5640 case OPC2_32_RC_RSUB:
5641 tcg_gen_movi_tl(temp, const9);
5642 gen_sub_d(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5643 break;
5644 case OPC2_32_RC_RSUBS:
5645 tcg_gen_movi_tl(temp, const9);
5646 gen_subs(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5647 break;
5648 case OPC2_32_RC_RSUBS_U:
5649 tcg_gen_movi_tl(temp, const9);
5650 gen_subsu(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5651 break;
5652 case OPC2_32_RC_SH_EQ:
5653 gen_sh_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5654 break;
5655 case OPC2_32_RC_SH_GE:
5656 gen_sh_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5657 break;
5658 case OPC2_32_RC_SH_GE_U:
5659 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5660 gen_sh_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5661 break;
5662 case OPC2_32_RC_SH_LT:
5663 gen_sh_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5664 break;
5665 case OPC2_32_RC_SH_LT_U:
5666 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5667 gen_sh_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5668 break;
5669 case OPC2_32_RC_SH_NE:
5670 gen_sh_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5671 break;
5672 case OPC2_32_RC_XOR_EQ:
5673 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5674 const9, &tcg_gen_xor_tl);
5675 break;
5676 case OPC2_32_RC_XOR_GE:
5677 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5678 const9, &tcg_gen_xor_tl);
5679 break;
5680 case OPC2_32_RC_XOR_GE_U:
5681 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5682 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5683 const9, &tcg_gen_xor_tl);
5684 break;
5685 case OPC2_32_RC_XOR_LT:
5686 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5687 const9, &tcg_gen_xor_tl);
5688 break;
5689 case OPC2_32_RC_XOR_LT_U:
5690 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5691 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5692 const9, &tcg_gen_xor_tl);
5693 break;
5694 case OPC2_32_RC_XOR_NE:
5695 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5696 const9, &tcg_gen_xor_tl);
5697 break;
5698 default:
5699 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5701 tcg_temp_free(temp);
5704 static void decode_rc_serviceroutine(DisasContext *ctx)
5706 uint32_t op2;
5707 uint32_t const9;
5709 op2 = MASK_OP_RC_OP2(ctx->opcode);
5710 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5712 switch (op2) {
5713 case OPC2_32_RC_BISR:
5714 gen_helper_1arg(bisr, const9);
5715 break;
5716 case OPC2_32_RC_SYSCALL:
5717 /* TODO: Add exception generation */
5718 break;
5719 default:
5720 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5724 static void decode_rc_mul(DisasContext *ctx)
5726 uint32_t op2;
5727 int r1, r2;
5728 int16_t const9;
5730 r2 = MASK_OP_RC_D(ctx->opcode);
5731 r1 = MASK_OP_RC_S1(ctx->opcode);
5732 const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
5734 op2 = MASK_OP_RC_OP2(ctx->opcode);
5736 switch (op2) {
5737 case OPC2_32_RC_MUL_32:
5738 gen_muli_i32s(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5739 break;
5740 case OPC2_32_RC_MUL_64:
5741 CHECK_REG_PAIR(r2);
5742 gen_muli_i64s(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
5743 break;
5744 case OPC2_32_RC_MULS_32:
5745 gen_mulsi_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5746 break;
5747 case OPC2_32_RC_MUL_U_64:
5748 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5749 CHECK_REG_PAIR(r2);
5750 gen_muli_i64u(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
5751 break;
5752 case OPC2_32_RC_MULS_U_32:
5753 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5754 gen_mulsui_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5755 break;
5756 default:
5757 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5761 /* RCPW format */
5762 static void decode_rcpw_insert(DisasContext *ctx)
5764 uint32_t op2;
5765 int r1, r2;
5766 int32_t pos, width, const4;
5768 TCGv temp;
5770 op2 = MASK_OP_RCPW_OP2(ctx->opcode);
5771 r1 = MASK_OP_RCPW_S1(ctx->opcode);
5772 r2 = MASK_OP_RCPW_D(ctx->opcode);
5773 const4 = MASK_OP_RCPW_CONST4(ctx->opcode);
5774 width = MASK_OP_RCPW_WIDTH(ctx->opcode);
5775 pos = MASK_OP_RCPW_POS(ctx->opcode);
5777 switch (op2) {
5778 case OPC2_32_RCPW_IMASK:
5779 CHECK_REG_PAIR(r2);
5780 /* if pos + width > 32 undefined result */
5781 if (pos + width <= 32) {
5782 tcg_gen_movi_tl(cpu_gpr_d[r2+1], ((1u << width) - 1) << pos);
5783 tcg_gen_movi_tl(cpu_gpr_d[r2], (const4 << pos));
5785 break;
5786 case OPC2_32_RCPW_INSERT:
5787 /* if pos + width > 32 undefined result */
5788 if (pos + width <= 32) {
5789 temp = tcg_const_i32(const4);
5790 tcg_gen_deposit_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, pos, width);
5791 tcg_temp_free(temp);
5793 break;
5794 default:
5795 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5799 /* RCRW format */
5801 static void decode_rcrw_insert(DisasContext *ctx)
5803 uint32_t op2;
5804 int r1, r3, r4;
5805 int32_t width, const4;
5807 TCGv temp, temp2, temp3;
5809 op2 = MASK_OP_RCRW_OP2(ctx->opcode);
5810 r1 = MASK_OP_RCRW_S1(ctx->opcode);
5811 r3 = MASK_OP_RCRW_S3(ctx->opcode);
5812 r4 = MASK_OP_RCRW_D(ctx->opcode);
5813 width = MASK_OP_RCRW_WIDTH(ctx->opcode);
5814 const4 = MASK_OP_RCRW_CONST4(ctx->opcode);
5816 temp = tcg_temp_new();
5817 temp2 = tcg_temp_new();
5819 switch (op2) {
5820 case OPC2_32_RCRW_IMASK:
5821 tcg_gen_andi_tl(temp, cpu_gpr_d[r4], 0x1f);
5822 tcg_gen_movi_tl(temp2, (1 << width) - 1);
5823 tcg_gen_shl_tl(cpu_gpr_d[r3 + 1], temp2, temp);
5824 tcg_gen_movi_tl(temp2, const4);
5825 tcg_gen_shl_tl(cpu_gpr_d[r3], temp2, temp);
5826 break;
5827 case OPC2_32_RCRW_INSERT:
5828 temp3 = tcg_temp_new();
5830 tcg_gen_movi_tl(temp, width);
5831 tcg_gen_movi_tl(temp2, const4);
5832 tcg_gen_andi_tl(temp3, cpu_gpr_d[r4], 0x1f);
5833 gen_insert(cpu_gpr_d[r3], cpu_gpr_d[r1], temp2, temp, temp3);
5835 tcg_temp_free(temp3);
5836 break;
5837 default:
5838 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5840 tcg_temp_free(temp);
5841 tcg_temp_free(temp2);
5844 /* RCR format */
5846 static void decode_rcr_cond_select(DisasContext *ctx)
5848 uint32_t op2;
5849 int r1, r3, r4;
5850 int32_t const9;
5852 TCGv temp, temp2;
5854 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5855 r1 = MASK_OP_RCR_S1(ctx->opcode);
5856 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5857 r3 = MASK_OP_RCR_S3(ctx->opcode);
5858 r4 = MASK_OP_RCR_D(ctx->opcode);
5860 switch (op2) {
5861 case OPC2_32_RCR_CADD:
5862 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const9, cpu_gpr_d[r4],
5863 cpu_gpr_d[r3]);
5864 break;
5865 case OPC2_32_RCR_CADDN:
5866 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const9, cpu_gpr_d[r4],
5867 cpu_gpr_d[r3]);
5868 break;
5869 case OPC2_32_RCR_SEL:
5870 temp = tcg_const_i32(0);
5871 temp2 = tcg_const_i32(const9);
5872 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
5873 cpu_gpr_d[r1], temp2);
5874 tcg_temp_free(temp);
5875 tcg_temp_free(temp2);
5876 break;
5877 case OPC2_32_RCR_SELN:
5878 temp = tcg_const_i32(0);
5879 temp2 = tcg_const_i32(const9);
5880 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
5881 cpu_gpr_d[r1], temp2);
5882 tcg_temp_free(temp);
5883 tcg_temp_free(temp2);
5884 break;
5885 default:
5886 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5890 static void decode_rcr_madd(DisasContext *ctx)
5892 uint32_t op2;
5893 int r1, r3, r4;
5894 int32_t const9;
5897 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5898 r1 = MASK_OP_RCR_S1(ctx->opcode);
5899 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5900 r3 = MASK_OP_RCR_S3(ctx->opcode);
5901 r4 = MASK_OP_RCR_D(ctx->opcode);
5903 switch (op2) {
5904 case OPC2_32_RCR_MADD_32:
5905 gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5906 break;
5907 case OPC2_32_RCR_MADD_64:
5908 CHECK_REG_PAIR(r4);
5909 CHECK_REG_PAIR(r3);
5910 gen_maddi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5911 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5912 break;
5913 case OPC2_32_RCR_MADDS_32:
5914 gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5915 break;
5916 case OPC2_32_RCR_MADDS_64:
5917 CHECK_REG_PAIR(r4);
5918 CHECK_REG_PAIR(r3);
5919 gen_maddsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5920 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5921 break;
5922 case OPC2_32_RCR_MADD_U_64:
5923 CHECK_REG_PAIR(r4);
5924 CHECK_REG_PAIR(r3);
5925 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5926 gen_maddui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5927 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5928 break;
5929 case OPC2_32_RCR_MADDS_U_32:
5930 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5931 gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5932 break;
5933 case OPC2_32_RCR_MADDS_U_64:
5934 CHECK_REG_PAIR(r4);
5935 CHECK_REG_PAIR(r3);
5936 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5937 gen_maddsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5938 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5939 break;
5940 default:
5941 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5945 static void decode_rcr_msub(DisasContext *ctx)
5947 uint32_t op2;
5948 int r1, r3, r4;
5949 int32_t const9;
5952 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5953 r1 = MASK_OP_RCR_S1(ctx->opcode);
5954 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5955 r3 = MASK_OP_RCR_S3(ctx->opcode);
5956 r4 = MASK_OP_RCR_D(ctx->opcode);
5958 switch (op2) {
5959 case OPC2_32_RCR_MSUB_32:
5960 gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5961 break;
5962 case OPC2_32_RCR_MSUB_64:
5963 CHECK_REG_PAIR(r4);
5964 CHECK_REG_PAIR(r3);
5965 gen_msubi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5966 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5967 break;
5968 case OPC2_32_RCR_MSUBS_32:
5969 gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5970 break;
5971 case OPC2_32_RCR_MSUBS_64:
5972 CHECK_REG_PAIR(r4);
5973 CHECK_REG_PAIR(r3);
5974 gen_msubsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5975 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5976 break;
5977 case OPC2_32_RCR_MSUB_U_64:
5978 CHECK_REG_PAIR(r4);
5979 CHECK_REG_PAIR(r3);
5980 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5981 gen_msubui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5982 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5983 break;
5984 case OPC2_32_RCR_MSUBS_U_32:
5985 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5986 gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5987 break;
5988 case OPC2_32_RCR_MSUBS_U_64:
5989 CHECK_REG_PAIR(r4);
5990 CHECK_REG_PAIR(r3);
5991 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5992 gen_msubsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5993 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5994 break;
5995 default:
5996 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6000 /* RLC format */
6002 static void decode_rlc_opc(DisasContext *ctx,
6003 uint32_t op1)
6005 int32_t const16;
6006 int r1, r2;
6008 const16 = MASK_OP_RLC_CONST16_SEXT(ctx->opcode);
6009 r1 = MASK_OP_RLC_S1(ctx->opcode);
6010 r2 = MASK_OP_RLC_D(ctx->opcode);
6012 switch (op1) {
6013 case OPC1_32_RLC_ADDI:
6014 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const16);
6015 break;
6016 case OPC1_32_RLC_ADDIH:
6017 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const16 << 16);
6018 break;
6019 case OPC1_32_RLC_ADDIH_A:
6020 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
6021 break;
6022 case OPC1_32_RLC_MFCR:
6023 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
6024 gen_mfcr(ctx, cpu_gpr_d[r2], const16);
6025 break;
6026 case OPC1_32_RLC_MOV:
6027 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
6028 break;
6029 case OPC1_32_RLC_MOV_64:
6030 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6031 CHECK_REG_PAIR(r2);
6032 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
6033 tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15);
6034 } else {
6035 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6037 break;
6038 case OPC1_32_RLC_MOV_U:
6039 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
6040 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
6041 break;
6042 case OPC1_32_RLC_MOV_H:
6043 tcg_gen_movi_tl(cpu_gpr_d[r2], const16 << 16);
6044 break;
6045 case OPC1_32_RLC_MOVH_A:
6046 tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
6047 break;
6048 case OPC1_32_RLC_MTCR:
6049 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
6050 gen_mtcr(ctx, cpu_gpr_d[r1], const16);
6051 break;
6052 default:
6053 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6057 /* RR format */
6058 static void decode_rr_accumulator(DisasContext *ctx)
6060 uint32_t op2;
6061 int r3, r2, r1;
6063 TCGv temp;
6065 r3 = MASK_OP_RR_D(ctx->opcode);
6066 r2 = MASK_OP_RR_S2(ctx->opcode);
6067 r1 = MASK_OP_RR_S1(ctx->opcode);
6068 op2 = MASK_OP_RR_OP2(ctx->opcode);
6070 switch (op2) {
6071 case OPC2_32_RR_ABS:
6072 gen_abs(cpu_gpr_d[r3], cpu_gpr_d[r2]);
6073 break;
6074 case OPC2_32_RR_ABS_B:
6075 gen_helper_abs_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
6076 break;
6077 case OPC2_32_RR_ABS_H:
6078 gen_helper_abs_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
6079 break;
6080 case OPC2_32_RR_ABSDIF:
6081 gen_absdif(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6082 break;
6083 case OPC2_32_RR_ABSDIF_B:
6084 gen_helper_absdif_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6085 cpu_gpr_d[r2]);
6086 break;
6087 case OPC2_32_RR_ABSDIF_H:
6088 gen_helper_absdif_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6089 cpu_gpr_d[r2]);
6090 break;
6091 case OPC2_32_RR_ABSDIFS:
6092 gen_helper_absdif_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6093 cpu_gpr_d[r2]);
6094 break;
6095 case OPC2_32_RR_ABSDIFS_H:
6096 gen_helper_absdif_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6097 cpu_gpr_d[r2]);
6098 break;
6099 case OPC2_32_RR_ABSS:
6100 gen_helper_abs_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
6101 break;
6102 case OPC2_32_RR_ABSS_H:
6103 gen_helper_abs_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
6104 break;
6105 case OPC2_32_RR_ADD:
6106 gen_add_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6107 break;
6108 case OPC2_32_RR_ADD_B:
6109 gen_helper_add_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6110 break;
6111 case OPC2_32_RR_ADD_H:
6112 gen_helper_add_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6113 break;
6114 case OPC2_32_RR_ADDC:
6115 gen_addc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6116 break;
6117 case OPC2_32_RR_ADDS:
6118 gen_adds(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6119 break;
6120 case OPC2_32_RR_ADDS_H:
6121 gen_helper_add_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6122 cpu_gpr_d[r2]);
6123 break;
6124 case OPC2_32_RR_ADDS_HU:
6125 gen_helper_add_h_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6126 cpu_gpr_d[r2]);
6127 break;
6128 case OPC2_32_RR_ADDS_U:
6129 gen_helper_add_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6130 cpu_gpr_d[r2]);
6131 break;
6132 case OPC2_32_RR_ADDX:
6133 gen_add_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6134 break;
6135 case OPC2_32_RR_AND_EQ:
6136 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
6137 cpu_gpr_d[r2], &tcg_gen_and_tl);
6138 break;
6139 case OPC2_32_RR_AND_GE:
6140 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6141 cpu_gpr_d[r2], &tcg_gen_and_tl);
6142 break;
6143 case OPC2_32_RR_AND_GE_U:
6144 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6145 cpu_gpr_d[r2], &tcg_gen_and_tl);
6146 break;
6147 case OPC2_32_RR_AND_LT:
6148 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6149 cpu_gpr_d[r2], &tcg_gen_and_tl);
6150 break;
6151 case OPC2_32_RR_AND_LT_U:
6152 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6153 cpu_gpr_d[r2], &tcg_gen_and_tl);
6154 break;
6155 case OPC2_32_RR_AND_NE:
6156 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6157 cpu_gpr_d[r2], &tcg_gen_and_tl);
6158 break;
6159 case OPC2_32_RR_EQ:
6160 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
6161 cpu_gpr_d[r2]);
6162 break;
6163 case OPC2_32_RR_EQ_B:
6164 gen_helper_eq_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6165 break;
6166 case OPC2_32_RR_EQ_H:
6167 gen_helper_eq_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6168 break;
6169 case OPC2_32_RR_EQ_W:
6170 gen_cond_w(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6171 break;
6172 case OPC2_32_RR_EQANY_B:
6173 gen_helper_eqany_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6174 break;
6175 case OPC2_32_RR_EQANY_H:
6176 gen_helper_eqany_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6177 break;
6178 case OPC2_32_RR_GE:
6179 tcg_gen_setcond_tl(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6180 cpu_gpr_d[r2]);
6181 break;
6182 case OPC2_32_RR_GE_U:
6183 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6184 cpu_gpr_d[r2]);
6185 break;
6186 case OPC2_32_RR_LT:
6187 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6188 cpu_gpr_d[r2]);
6189 break;
6190 case OPC2_32_RR_LT_U:
6191 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6192 cpu_gpr_d[r2]);
6193 break;
6194 case OPC2_32_RR_LT_B:
6195 gen_helper_lt_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6196 break;
6197 case OPC2_32_RR_LT_BU:
6198 gen_helper_lt_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6199 break;
6200 case OPC2_32_RR_LT_H:
6201 gen_helper_lt_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6202 break;
6203 case OPC2_32_RR_LT_HU:
6204 gen_helper_lt_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6205 break;
6206 case OPC2_32_RR_LT_W:
6207 gen_cond_w(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6208 break;
6209 case OPC2_32_RR_LT_WU:
6210 gen_cond_w(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6211 break;
6212 case OPC2_32_RR_MAX:
6213 tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6214 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6215 break;
6216 case OPC2_32_RR_MAX_U:
6217 tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6218 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6219 break;
6220 case OPC2_32_RR_MAX_B:
6221 gen_helper_max_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6222 break;
6223 case OPC2_32_RR_MAX_BU:
6224 gen_helper_max_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6225 break;
6226 case OPC2_32_RR_MAX_H:
6227 gen_helper_max_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6228 break;
6229 case OPC2_32_RR_MAX_HU:
6230 gen_helper_max_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6231 break;
6232 case OPC2_32_RR_MIN:
6233 tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6234 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6235 break;
6236 case OPC2_32_RR_MIN_U:
6237 tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6238 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6239 break;
6240 case OPC2_32_RR_MIN_B:
6241 gen_helper_min_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6242 break;
6243 case OPC2_32_RR_MIN_BU:
6244 gen_helper_min_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6245 break;
6246 case OPC2_32_RR_MIN_H:
6247 gen_helper_min_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6248 break;
6249 case OPC2_32_RR_MIN_HU:
6250 gen_helper_min_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6251 break;
6252 case OPC2_32_RR_MOV:
6253 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
6254 break;
6255 case OPC2_32_RR_MOV_64:
6256 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6257 temp = tcg_temp_new();
6259 CHECK_REG_PAIR(r3);
6260 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
6261 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
6262 tcg_gen_mov_tl(cpu_gpr_d[r3 + 1], temp);
6264 tcg_temp_free(temp);
6265 } else {
6266 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6268 break;
6269 case OPC2_32_RR_MOVS_64:
6270 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6271 CHECK_REG_PAIR(r3);
6272 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
6273 tcg_gen_sari_tl(cpu_gpr_d[r3 + 1], cpu_gpr_d[r2], 31);
6274 } else {
6275 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6277 break;
6278 case OPC2_32_RR_NE:
6279 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6280 cpu_gpr_d[r2]);
6281 break;
6282 case OPC2_32_RR_OR_EQ:
6283 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
6284 cpu_gpr_d[r2], &tcg_gen_or_tl);
6285 break;
6286 case OPC2_32_RR_OR_GE:
6287 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6288 cpu_gpr_d[r2], &tcg_gen_or_tl);
6289 break;
6290 case OPC2_32_RR_OR_GE_U:
6291 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6292 cpu_gpr_d[r2], &tcg_gen_or_tl);
6293 break;
6294 case OPC2_32_RR_OR_LT:
6295 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6296 cpu_gpr_d[r2], &tcg_gen_or_tl);
6297 break;
6298 case OPC2_32_RR_OR_LT_U:
6299 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6300 cpu_gpr_d[r2], &tcg_gen_or_tl);
6301 break;
6302 case OPC2_32_RR_OR_NE:
6303 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6304 cpu_gpr_d[r2], &tcg_gen_or_tl);
6305 break;
6306 case OPC2_32_RR_SAT_B:
6307 gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7f, -0x80);
6308 break;
6309 case OPC2_32_RR_SAT_BU:
6310 gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xff);
6311 break;
6312 case OPC2_32_RR_SAT_H:
6313 gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7fff, -0x8000);
6314 break;
6315 case OPC2_32_RR_SAT_HU:
6316 gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xffff);
6317 break;
6318 case OPC2_32_RR_SH_EQ:
6319 gen_sh_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
6320 cpu_gpr_d[r2]);
6321 break;
6322 case OPC2_32_RR_SH_GE:
6323 gen_sh_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6324 cpu_gpr_d[r2]);
6325 break;
6326 case OPC2_32_RR_SH_GE_U:
6327 gen_sh_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6328 cpu_gpr_d[r2]);
6329 break;
6330 case OPC2_32_RR_SH_LT:
6331 gen_sh_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6332 cpu_gpr_d[r2]);
6333 break;
6334 case OPC2_32_RR_SH_LT_U:
6335 gen_sh_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6336 cpu_gpr_d[r2]);
6337 break;
6338 case OPC2_32_RR_SH_NE:
6339 gen_sh_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6340 cpu_gpr_d[r2]);
6341 break;
6342 case OPC2_32_RR_SUB:
6343 gen_sub_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6344 break;
6345 case OPC2_32_RR_SUB_B:
6346 gen_helper_sub_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6347 break;
6348 case OPC2_32_RR_SUB_H:
6349 gen_helper_sub_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6350 break;
6351 case OPC2_32_RR_SUBC:
6352 gen_subc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6353 break;
6354 case OPC2_32_RR_SUBS:
6355 gen_subs(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6356 break;
6357 case OPC2_32_RR_SUBS_U:
6358 gen_subsu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6359 break;
6360 case OPC2_32_RR_SUBS_H:
6361 gen_helper_sub_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6362 cpu_gpr_d[r2]);
6363 break;
6364 case OPC2_32_RR_SUBS_HU:
6365 gen_helper_sub_h_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6366 cpu_gpr_d[r2]);
6367 break;
6368 case OPC2_32_RR_SUBX:
6369 gen_sub_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6370 break;
6371 case OPC2_32_RR_XOR_EQ:
6372 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
6373 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6374 break;
6375 case OPC2_32_RR_XOR_GE:
6376 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6377 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6378 break;
6379 case OPC2_32_RR_XOR_GE_U:
6380 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6381 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6382 break;
6383 case OPC2_32_RR_XOR_LT:
6384 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
6385 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6386 break;
6387 case OPC2_32_RR_XOR_LT_U:
6388 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
6389 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6390 break;
6391 case OPC2_32_RR_XOR_NE:
6392 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
6393 cpu_gpr_d[r2], &tcg_gen_xor_tl);
6394 break;
6395 default:
6396 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6400 static void decode_rr_logical_shift(DisasContext *ctx)
6402 uint32_t op2;
6403 int r3, r2, r1;
6404 TCGv temp;
6406 r3 = MASK_OP_RR_D(ctx->opcode);
6407 r2 = MASK_OP_RR_S2(ctx->opcode);
6408 r1 = MASK_OP_RR_S1(ctx->opcode);
6410 temp = tcg_temp_new();
6411 op2 = MASK_OP_RR_OP2(ctx->opcode);
6413 switch (op2) {
6414 case OPC2_32_RR_AND:
6415 tcg_gen_and_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6416 break;
6417 case OPC2_32_RR_ANDN:
6418 tcg_gen_andc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6419 break;
6420 case OPC2_32_RR_CLO:
6421 tcg_gen_not_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6422 tcg_gen_clzi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], TARGET_LONG_BITS);
6423 break;
6424 case OPC2_32_RR_CLO_H:
6425 gen_helper_clo_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6426 break;
6427 case OPC2_32_RR_CLS:
6428 tcg_gen_clrsb_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6429 break;
6430 case OPC2_32_RR_CLS_H:
6431 gen_helper_cls_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6432 break;
6433 case OPC2_32_RR_CLZ:
6434 tcg_gen_clzi_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], TARGET_LONG_BITS);
6435 break;
6436 case OPC2_32_RR_CLZ_H:
6437 gen_helper_clz_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6438 break;
6439 case OPC2_32_RR_NAND:
6440 tcg_gen_nand_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6441 break;
6442 case OPC2_32_RR_NOR:
6443 tcg_gen_nor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6444 break;
6445 case OPC2_32_RR_OR:
6446 tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6447 break;
6448 case OPC2_32_RR_ORN:
6449 tcg_gen_orc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6450 break;
6451 case OPC2_32_RR_SH:
6452 gen_helper_sh(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6453 break;
6454 case OPC2_32_RR_SH_H:
6455 gen_helper_sh_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6456 break;
6457 case OPC2_32_RR_SHA:
6458 gen_helper_sha(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6459 break;
6460 case OPC2_32_RR_SHA_H:
6461 gen_helper_sha_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6462 break;
6463 case OPC2_32_RR_SHAS:
6464 gen_shas(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6465 break;
6466 case OPC2_32_RR_XNOR:
6467 tcg_gen_eqv_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6468 break;
6469 case OPC2_32_RR_XOR:
6470 tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6471 break;
6472 default:
6473 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6475 tcg_temp_free(temp);
6478 static void decode_rr_address(DisasContext *ctx)
6480 uint32_t op2, n;
6481 int r1, r2, r3;
6482 TCGv temp;
6484 op2 = MASK_OP_RR_OP2(ctx->opcode);
6485 r3 = MASK_OP_RR_D(ctx->opcode);
6486 r2 = MASK_OP_RR_S2(ctx->opcode);
6487 r1 = MASK_OP_RR_S1(ctx->opcode);
6488 n = MASK_OP_RR_N(ctx->opcode);
6490 switch (op2) {
6491 case OPC2_32_RR_ADD_A:
6492 tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
6493 break;
6494 case OPC2_32_RR_ADDSC_A:
6495 temp = tcg_temp_new();
6496 tcg_gen_shli_tl(temp, cpu_gpr_d[r1], n);
6497 tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r2], temp);
6498 tcg_temp_free(temp);
6499 break;
6500 case OPC2_32_RR_ADDSC_AT:
6501 temp = tcg_temp_new();
6502 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 3);
6503 tcg_gen_add_tl(temp, cpu_gpr_a[r2], temp);
6504 tcg_gen_andi_tl(cpu_gpr_a[r3], temp, 0xFFFFFFFC);
6505 tcg_temp_free(temp);
6506 break;
6507 case OPC2_32_RR_EQ_A:
6508 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1],
6509 cpu_gpr_a[r2]);
6510 break;
6511 case OPC2_32_RR_EQZ:
6512 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
6513 break;
6514 case OPC2_32_RR_GE_A:
6515 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_a[r1],
6516 cpu_gpr_a[r2]);
6517 break;
6518 case OPC2_32_RR_LT_A:
6519 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_a[r1],
6520 cpu_gpr_a[r2]);
6521 break;
6522 case OPC2_32_RR_MOV_A:
6523 tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_d[r2]);
6524 break;
6525 case OPC2_32_RR_MOV_AA:
6526 tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_a[r2]);
6527 break;
6528 case OPC2_32_RR_MOV_D:
6529 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_a[r2]);
6530 break;
6531 case OPC2_32_RR_NE_A:
6532 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1],
6533 cpu_gpr_a[r2]);
6534 break;
6535 case OPC2_32_RR_NEZ_A:
6536 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
6537 break;
6538 case OPC2_32_RR_SUB_A:
6539 tcg_gen_sub_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
6540 break;
6541 default:
6542 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6546 static void decode_rr_idirect(DisasContext *ctx)
6548 uint32_t op2;
6549 int r1;
6551 op2 = MASK_OP_RR_OP2(ctx->opcode);
6552 r1 = MASK_OP_RR_S1(ctx->opcode);
6554 switch (op2) {
6555 case OPC2_32_RR_JI:
6556 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6557 break;
6558 case OPC2_32_RR_JLI:
6559 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
6560 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6561 break;
6562 case OPC2_32_RR_CALLI:
6563 gen_helper_1arg(call, ctx->pc_succ_insn);
6564 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6565 break;
6566 case OPC2_32_RR_FCALLI:
6567 gen_fcall_save_ctx(ctx);
6568 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6569 break;
6570 default:
6571 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6573 tcg_gen_exit_tb(NULL, 0);
6574 ctx->base.is_jmp = DISAS_NORETURN;
6577 static void decode_rr_divide(DisasContext *ctx)
6579 uint32_t op2;
6580 int r1, r2, r3;
6582 TCGv temp, temp2, temp3;
6584 op2 = MASK_OP_RR_OP2(ctx->opcode);
6585 r3 = MASK_OP_RR_D(ctx->opcode);
6586 r2 = MASK_OP_RR_S2(ctx->opcode);
6587 r1 = MASK_OP_RR_S1(ctx->opcode);
6589 switch (op2) {
6590 case OPC2_32_RR_BMERGE:
6591 gen_helper_bmerge(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6592 break;
6593 case OPC2_32_RR_BSPLIT:
6594 CHECK_REG_PAIR(r3);
6595 gen_bsplit(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
6596 break;
6597 case OPC2_32_RR_DVINIT_B:
6598 CHECK_REG_PAIR(r3);
6599 gen_dvinit_b(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6600 cpu_gpr_d[r2]);
6601 break;
6602 case OPC2_32_RR_DVINIT_BU:
6603 temp = tcg_temp_new();
6604 temp2 = tcg_temp_new();
6605 temp3 = tcg_temp_new();
6606 CHECK_REG_PAIR(r3);
6607 tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8);
6608 /* reset av */
6609 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6610 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
6611 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
6612 tcg_gen_abs_tl(temp, temp3);
6613 tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
6614 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
6615 } else {
6616 /* overflow = (D[b] == 0) */
6617 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6619 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6620 /* sv */
6621 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6622 /* write result */
6623 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 24);
6624 tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
6626 tcg_temp_free(temp);
6627 tcg_temp_free(temp2);
6628 tcg_temp_free(temp3);
6629 break;
6630 case OPC2_32_RR_DVINIT_H:
6631 CHECK_REG_PAIR(r3);
6632 gen_dvinit_h(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6633 cpu_gpr_d[r2]);
6634 break;
6635 case OPC2_32_RR_DVINIT_HU:
6636 temp = tcg_temp_new();
6637 temp2 = tcg_temp_new();
6638 temp3 = tcg_temp_new();
6639 CHECK_REG_PAIR(r3);
6640 tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16);
6641 /* reset av */
6642 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6643 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
6644 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
6645 tcg_gen_abs_tl(temp, temp3);
6646 tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
6647 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
6648 } else {
6649 /* overflow = (D[b] == 0) */
6650 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6652 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6653 /* sv */
6654 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6655 /* write result */
6656 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 16);
6657 tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
6658 tcg_temp_free(temp);
6659 tcg_temp_free(temp2);
6660 tcg_temp_free(temp3);
6661 break;
6662 case OPC2_32_RR_DVINIT:
6663 temp = tcg_temp_new();
6664 temp2 = tcg_temp_new();
6665 CHECK_REG_PAIR(r3);
6666 /* overflow = ((D[b] == 0) ||
6667 ((D[b] == 0xFFFFFFFF) && (D[a] == 0x80000000))) */
6668 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, cpu_gpr_d[r2], 0xffffffff);
6669 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r1], 0x80000000);
6670 tcg_gen_and_tl(temp, temp, temp2);
6671 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r2], 0);
6672 tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
6673 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6674 /* sv */
6675 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6676 /* reset av */
6677 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6678 /* write result */
6679 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6680 /* sign extend to high reg */
6681 tcg_gen_sari_tl(cpu_gpr_d[r3+1], cpu_gpr_d[r1], 31);
6682 tcg_temp_free(temp);
6683 tcg_temp_free(temp2);
6684 break;
6685 case OPC2_32_RR_DVINIT_U:
6686 /* overflow = (D[b] == 0) */
6687 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6688 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6689 /* sv */
6690 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6691 /* reset av */
6692 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6693 /* write result */
6694 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6695 /* zero extend to high reg*/
6696 tcg_gen_movi_tl(cpu_gpr_d[r3+1], 0);
6697 break;
6698 case OPC2_32_RR_PARITY:
6699 gen_helper_parity(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6700 break;
6701 case OPC2_32_RR_UNPACK:
6702 CHECK_REG_PAIR(r3);
6703 gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
6704 break;
6705 case OPC2_32_RR_CRC32:
6706 if (has_feature(ctx, TRICORE_FEATURE_161)) {
6707 gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6708 } else {
6709 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6711 break;
6712 case OPC2_32_RR_DIV:
6713 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6714 GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6715 cpu_gpr_d[r2]);
6716 } else {
6717 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6719 break;
6720 case OPC2_32_RR_DIV_U:
6721 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6722 GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
6723 cpu_gpr_d[r1], cpu_gpr_d[r2]);
6724 } else {
6725 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6727 break;
6728 case OPC2_32_RR_MUL_F:
6729 gen_helper_fmul(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6730 break;
6731 case OPC2_32_RR_DIV_F:
6732 gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6733 break;
6734 case OPC2_32_RR_CMP_F:
6735 gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6736 break;
6737 case OPC2_32_RR_FTOI:
6738 gen_helper_ftoi(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6739 break;
6740 case OPC2_32_RR_ITOF:
6741 gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6742 break;
6743 case OPC2_32_RR_FTOUZ:
6744 gen_helper_ftouz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6745 break;
6746 case OPC2_32_RR_UPDFL:
6747 gen_helper_updfl(cpu_env, cpu_gpr_d[r1]);
6748 break;
6749 case OPC2_32_RR_UTOF:
6750 gen_helper_utof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6751 break;
6752 case OPC2_32_RR_FTOIZ:
6753 gen_helper_ftoiz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6754 break;
6755 case OPC2_32_RR_QSEED_F:
6756 gen_helper_qseed(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
6757 break;
6758 default:
6759 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6763 /* RR1 Format */
6764 static void decode_rr1_mul(DisasContext *ctx)
6766 uint32_t op2;
6768 int r1, r2, r3;
6769 TCGv n;
6770 TCGv_i64 temp64;
6772 r1 = MASK_OP_RR1_S1(ctx->opcode);
6773 r2 = MASK_OP_RR1_S2(ctx->opcode);
6774 r3 = MASK_OP_RR1_D(ctx->opcode);
6775 n = tcg_const_i32(MASK_OP_RR1_N(ctx->opcode));
6776 op2 = MASK_OP_RR1_OP2(ctx->opcode);
6778 switch (op2) {
6779 case OPC2_32_RR1_MUL_H_32_LL:
6780 temp64 = tcg_temp_new_i64();
6781 CHECK_REG_PAIR(r3);
6782 GEN_HELPER_LL(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6783 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6784 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6785 tcg_temp_free_i64(temp64);
6786 break;
6787 case OPC2_32_RR1_MUL_H_32_LU:
6788 temp64 = tcg_temp_new_i64();
6789 CHECK_REG_PAIR(r3);
6790 GEN_HELPER_LU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6791 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6792 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6793 tcg_temp_free_i64(temp64);
6794 break;
6795 case OPC2_32_RR1_MUL_H_32_UL:
6796 temp64 = tcg_temp_new_i64();
6797 CHECK_REG_PAIR(r3);
6798 GEN_HELPER_UL(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6799 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6800 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6801 tcg_temp_free_i64(temp64);
6802 break;
6803 case OPC2_32_RR1_MUL_H_32_UU:
6804 temp64 = tcg_temp_new_i64();
6805 CHECK_REG_PAIR(r3);
6806 GEN_HELPER_UU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6807 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6808 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6809 tcg_temp_free_i64(temp64);
6810 break;
6811 case OPC2_32_RR1_MULM_H_64_LL:
6812 temp64 = tcg_temp_new_i64();
6813 CHECK_REG_PAIR(r3);
6814 GEN_HELPER_LL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6815 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6816 /* reset V bit */
6817 tcg_gen_movi_tl(cpu_PSW_V, 0);
6818 /* reset AV bit */
6819 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6820 tcg_temp_free_i64(temp64);
6821 break;
6822 case OPC2_32_RR1_MULM_H_64_LU:
6823 temp64 = tcg_temp_new_i64();
6824 CHECK_REG_PAIR(r3);
6825 GEN_HELPER_LU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6826 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6827 /* reset V bit */
6828 tcg_gen_movi_tl(cpu_PSW_V, 0);
6829 /* reset AV bit */
6830 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6831 tcg_temp_free_i64(temp64);
6832 break;
6833 case OPC2_32_RR1_MULM_H_64_UL:
6834 temp64 = tcg_temp_new_i64();
6835 CHECK_REG_PAIR(r3);
6836 GEN_HELPER_UL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6837 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6838 /* reset V bit */
6839 tcg_gen_movi_tl(cpu_PSW_V, 0);
6840 /* reset AV bit */
6841 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6842 tcg_temp_free_i64(temp64);
6843 break;
6844 case OPC2_32_RR1_MULM_H_64_UU:
6845 temp64 = tcg_temp_new_i64();
6846 CHECK_REG_PAIR(r3);
6847 GEN_HELPER_UU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6848 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6849 /* reset V bit */
6850 tcg_gen_movi_tl(cpu_PSW_V, 0);
6851 /* reset AV bit */
6852 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6853 tcg_temp_free_i64(temp64);
6855 break;
6856 case OPC2_32_RR1_MULR_H_16_LL:
6857 GEN_HELPER_LL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6858 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6859 break;
6860 case OPC2_32_RR1_MULR_H_16_LU:
6861 GEN_HELPER_LU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6862 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6863 break;
6864 case OPC2_32_RR1_MULR_H_16_UL:
6865 GEN_HELPER_UL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6866 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6867 break;
6868 case OPC2_32_RR1_MULR_H_16_UU:
6869 GEN_HELPER_UU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6870 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6871 break;
6872 default:
6873 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6875 tcg_temp_free(n);
6878 static void decode_rr1_mulq(DisasContext *ctx)
6880 uint32_t op2;
6881 int r1, r2, r3;
6882 uint32_t n;
6884 TCGv temp, temp2;
6886 r1 = MASK_OP_RR1_S1(ctx->opcode);
6887 r2 = MASK_OP_RR1_S2(ctx->opcode);
6888 r3 = MASK_OP_RR1_D(ctx->opcode);
6889 n = MASK_OP_RR1_N(ctx->opcode);
6890 op2 = MASK_OP_RR1_OP2(ctx->opcode);
6892 temp = tcg_temp_new();
6893 temp2 = tcg_temp_new();
6895 switch (op2) {
6896 case OPC2_32_RR1_MUL_Q_32:
6897 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], cpu_gpr_d[r2], n, 32);
6898 break;
6899 case OPC2_32_RR1_MUL_Q_64:
6900 CHECK_REG_PAIR(r3);
6901 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
6902 n, 0);
6903 break;
6904 case OPC2_32_RR1_MUL_Q_32_L:
6905 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
6906 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
6907 break;
6908 case OPC2_32_RR1_MUL_Q_64_L:
6909 CHECK_REG_PAIR(r3);
6910 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
6911 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
6912 break;
6913 case OPC2_32_RR1_MUL_Q_32_U:
6914 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
6915 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
6916 break;
6917 case OPC2_32_RR1_MUL_Q_64_U:
6918 CHECK_REG_PAIR(r3);
6919 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
6920 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
6921 break;
6922 case OPC2_32_RR1_MUL_Q_32_LL:
6923 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
6924 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
6925 gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
6926 break;
6927 case OPC2_32_RR1_MUL_Q_32_UU:
6928 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
6929 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
6930 gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
6931 break;
6932 case OPC2_32_RR1_MULR_Q_32_L:
6933 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
6934 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
6935 gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
6936 break;
6937 case OPC2_32_RR1_MULR_Q_32_U:
6938 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
6939 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
6940 gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
6941 break;
6942 default:
6943 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6945 tcg_temp_free(temp);
6946 tcg_temp_free(temp2);
6949 /* RR2 format */
6950 static void decode_rr2_mul(DisasContext *ctx)
6952 uint32_t op2;
6953 int r1, r2, r3;
6955 op2 = MASK_OP_RR2_OP2(ctx->opcode);
6956 r1 = MASK_OP_RR2_S1(ctx->opcode);
6957 r2 = MASK_OP_RR2_S2(ctx->opcode);
6958 r3 = MASK_OP_RR2_D(ctx->opcode);
6959 switch (op2) {
6960 case OPC2_32_RR2_MUL_32:
6961 gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6962 break;
6963 case OPC2_32_RR2_MUL_64:
6964 CHECK_REG_PAIR(r3);
6965 gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6966 cpu_gpr_d[r2]);
6967 break;
6968 case OPC2_32_RR2_MULS_32:
6969 gen_helper_mul_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6970 cpu_gpr_d[r2]);
6971 break;
6972 case OPC2_32_RR2_MUL_U_64:
6973 CHECK_REG_PAIR(r3);
6974 gen_mul_i64u(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6975 cpu_gpr_d[r2]);
6976 break;
6977 case OPC2_32_RR2_MULS_U_32:
6978 gen_helper_mul_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
6979 cpu_gpr_d[r2]);
6980 break;
6981 default:
6982 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6986 /* RRPW format */
6987 static void decode_rrpw_extract_insert(DisasContext *ctx)
6989 uint32_t op2;
6990 int r1, r2, r3;
6991 int32_t pos, width;
6992 TCGv temp;
6994 op2 = MASK_OP_RRPW_OP2(ctx->opcode);
6995 r1 = MASK_OP_RRPW_S1(ctx->opcode);
6996 r2 = MASK_OP_RRPW_S2(ctx->opcode);
6997 r3 = MASK_OP_RRPW_D(ctx->opcode);
6998 pos = MASK_OP_RRPW_POS(ctx->opcode);
6999 width = MASK_OP_RRPW_WIDTH(ctx->opcode);
7001 switch (op2) {
7002 case OPC2_32_RRPW_EXTR:
7003 if (width == 0) {
7004 tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
7005 break;
7008 if (pos + width <= 32) {
7009 /* optimize special cases */
7010 if ((pos == 0) && (width == 8)) {
7011 tcg_gen_ext8s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
7012 } else if ((pos == 0) && (width == 16)) {
7013 tcg_gen_ext16s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
7014 } else {
7015 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 32 - pos - width);
7016 tcg_gen_sari_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 32 - width);
7019 break;
7020 case OPC2_32_RRPW_EXTR_U:
7021 if (width == 0) {
7022 tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
7023 } else {
7024 tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos);
7025 tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], ~0u >> (32-width));
7027 break;
7028 case OPC2_32_RRPW_IMASK:
7029 CHECK_REG_PAIR(r3);
7031 if (pos + width <= 32) {
7032 temp = tcg_temp_new();
7033 tcg_gen_movi_tl(temp, ((1u << width) - 1) << pos);
7034 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], pos);
7035 tcg_gen_mov_tl(cpu_gpr_d[r3 + 1], temp);
7036 tcg_temp_free(temp);
7039 break;
7040 case OPC2_32_RRPW_INSERT:
7041 if (pos + width <= 32) {
7042 tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
7043 pos, width);
7045 break;
7046 default:
7047 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7051 /* RRR format */
7052 static void decode_rrr_cond_select(DisasContext *ctx)
7054 uint32_t op2;
7055 int r1, r2, r3, r4;
7056 TCGv temp;
7058 op2 = MASK_OP_RRR_OP2(ctx->opcode);
7059 r1 = MASK_OP_RRR_S1(ctx->opcode);
7060 r2 = MASK_OP_RRR_S2(ctx->opcode);
7061 r3 = MASK_OP_RRR_S3(ctx->opcode);
7062 r4 = MASK_OP_RRR_D(ctx->opcode);
7064 switch (op2) {
7065 case OPC2_32_RRR_CADD:
7066 gen_cond_add(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
7067 cpu_gpr_d[r4], cpu_gpr_d[r3]);
7068 break;
7069 case OPC2_32_RRR_CADDN:
7070 gen_cond_add(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7071 cpu_gpr_d[r3]);
7072 break;
7073 case OPC2_32_RRR_CSUB:
7074 gen_cond_sub(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7075 cpu_gpr_d[r3]);
7076 break;
7077 case OPC2_32_RRR_CSUBN:
7078 gen_cond_sub(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7079 cpu_gpr_d[r3]);
7080 break;
7081 case OPC2_32_RRR_SEL:
7082 temp = tcg_const_i32(0);
7083 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
7084 cpu_gpr_d[r1], cpu_gpr_d[r2]);
7085 tcg_temp_free(temp);
7086 break;
7087 case OPC2_32_RRR_SELN:
7088 temp = tcg_const_i32(0);
7089 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
7090 cpu_gpr_d[r1], cpu_gpr_d[r2]);
7091 tcg_temp_free(temp);
7092 break;
7093 default:
7094 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7098 static void decode_rrr_divide(DisasContext *ctx)
7100 uint32_t op2;
7102 int r1, r2, r3, r4;
7104 op2 = MASK_OP_RRR_OP2(ctx->opcode);
7105 r1 = MASK_OP_RRR_S1(ctx->opcode);
7106 r2 = MASK_OP_RRR_S2(ctx->opcode);
7107 r3 = MASK_OP_RRR_S3(ctx->opcode);
7108 r4 = MASK_OP_RRR_D(ctx->opcode);
7110 switch (op2) {
7111 case OPC2_32_RRR_DVADJ:
7112 CHECK_REG_PAIR(r3);
7113 CHECK_REG_PAIR(r4);
7114 GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7115 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7116 break;
7117 case OPC2_32_RRR_DVSTEP:
7118 CHECK_REG_PAIR(r3);
7119 CHECK_REG_PAIR(r4);
7120 GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7121 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7122 break;
7123 case OPC2_32_RRR_DVSTEP_U:
7124 CHECK_REG_PAIR(r3);
7125 CHECK_REG_PAIR(r4);
7126 GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7127 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7128 break;
7129 case OPC2_32_RRR_IXMAX:
7130 CHECK_REG_PAIR(r3);
7131 CHECK_REG_PAIR(r4);
7132 GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7133 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7134 break;
7135 case OPC2_32_RRR_IXMAX_U:
7136 CHECK_REG_PAIR(r3);
7137 CHECK_REG_PAIR(r4);
7138 GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7139 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7140 break;
7141 case OPC2_32_RRR_IXMIN:
7142 CHECK_REG_PAIR(r3);
7143 CHECK_REG_PAIR(r4);
7144 GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7145 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7146 break;
7147 case OPC2_32_RRR_IXMIN_U:
7148 CHECK_REG_PAIR(r3);
7149 CHECK_REG_PAIR(r4);
7150 GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7151 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7152 break;
7153 case OPC2_32_RRR_PACK:
7154 CHECK_REG_PAIR(r3);
7155 gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
7156 cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
7157 break;
7158 case OPC2_32_RRR_ADD_F:
7159 gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
7160 break;
7161 case OPC2_32_RRR_SUB_F:
7162 gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
7163 break;
7164 case OPC2_32_RRR_MADD_F:
7165 gen_helper_fmadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7166 cpu_gpr_d[r2], cpu_gpr_d[r3]);
7167 break;
7168 case OPC2_32_RRR_MSUB_F:
7169 gen_helper_fmsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7170 cpu_gpr_d[r2], cpu_gpr_d[r3]);
7171 break;
7172 default:
7173 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7177 /* RRR2 format */
7178 static void decode_rrr2_madd(DisasContext *ctx)
7180 uint32_t op2;
7181 uint32_t r1, r2, r3, r4;
7183 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
7184 r1 = MASK_OP_RRR2_S1(ctx->opcode);
7185 r2 = MASK_OP_RRR2_S2(ctx->opcode);
7186 r3 = MASK_OP_RRR2_S3(ctx->opcode);
7187 r4 = MASK_OP_RRR2_D(ctx->opcode);
7188 switch (op2) {
7189 case OPC2_32_RRR2_MADD_32:
7190 gen_madd32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
7191 cpu_gpr_d[r2]);
7192 break;
7193 case OPC2_32_RRR2_MADD_64:
7194 CHECK_REG_PAIR(r4);
7195 CHECK_REG_PAIR(r3);
7196 gen_madd64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7197 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7198 break;
7199 case OPC2_32_RRR2_MADDS_32:
7200 gen_helper_madd32_ssov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7201 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7202 break;
7203 case OPC2_32_RRR2_MADDS_64:
7204 CHECK_REG_PAIR(r4);
7205 CHECK_REG_PAIR(r3);
7206 gen_madds_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7207 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7208 break;
7209 case OPC2_32_RRR2_MADD_U_64:
7210 CHECK_REG_PAIR(r4);
7211 CHECK_REG_PAIR(r3);
7212 gen_maddu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7213 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7214 break;
7215 case OPC2_32_RRR2_MADDS_U_32:
7216 gen_helper_madd32_suov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7217 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7218 break;
7219 case OPC2_32_RRR2_MADDS_U_64:
7220 CHECK_REG_PAIR(r4);
7221 CHECK_REG_PAIR(r3);
7222 gen_maddsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7223 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7224 break;
7225 default:
7226 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7230 static void decode_rrr2_msub(DisasContext *ctx)
7232 uint32_t op2;
7233 uint32_t r1, r2, r3, r4;
7235 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
7236 r1 = MASK_OP_RRR2_S1(ctx->opcode);
7237 r2 = MASK_OP_RRR2_S2(ctx->opcode);
7238 r3 = MASK_OP_RRR2_S3(ctx->opcode);
7239 r4 = MASK_OP_RRR2_D(ctx->opcode);
7241 switch (op2) {
7242 case OPC2_32_RRR2_MSUB_32:
7243 gen_msub32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
7244 cpu_gpr_d[r2]);
7245 break;
7246 case OPC2_32_RRR2_MSUB_64:
7247 CHECK_REG_PAIR(r4);
7248 CHECK_REG_PAIR(r3);
7249 gen_msub64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7250 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7251 break;
7252 case OPC2_32_RRR2_MSUBS_32:
7253 gen_helper_msub32_ssov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7254 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7255 break;
7256 case OPC2_32_RRR2_MSUBS_64:
7257 CHECK_REG_PAIR(r4);
7258 CHECK_REG_PAIR(r3);
7259 gen_msubs_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7260 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7261 break;
7262 case OPC2_32_RRR2_MSUB_U_64:
7263 gen_msubu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7264 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7265 break;
7266 case OPC2_32_RRR2_MSUBS_U_32:
7267 gen_helper_msub32_suov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7268 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7269 break;
7270 case OPC2_32_RRR2_MSUBS_U_64:
7271 CHECK_REG_PAIR(r4);
7272 CHECK_REG_PAIR(r3);
7273 gen_msubsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7274 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7275 break;
7276 default:
7277 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7281 /* RRR1 format */
7282 static void decode_rrr1_madd(DisasContext *ctx)
7284 uint32_t op2;
7285 uint32_t r1, r2, r3, r4, n;
7287 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7288 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7289 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7290 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7291 r4 = MASK_OP_RRR1_D(ctx->opcode);
7292 n = MASK_OP_RRR1_N(ctx->opcode);
7294 switch (op2) {
7295 case OPC2_32_RRR1_MADD_H_LL:
7296 CHECK_REG_PAIR(r4);
7297 CHECK_REG_PAIR(r3);
7298 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7299 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7300 break;
7301 case OPC2_32_RRR1_MADD_H_LU:
7302 CHECK_REG_PAIR(r4);
7303 CHECK_REG_PAIR(r3);
7304 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7305 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7306 break;
7307 case OPC2_32_RRR1_MADD_H_UL:
7308 CHECK_REG_PAIR(r4);
7309 CHECK_REG_PAIR(r3);
7310 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7311 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7312 break;
7313 case OPC2_32_RRR1_MADD_H_UU:
7314 CHECK_REG_PAIR(r4);
7315 CHECK_REG_PAIR(r3);
7316 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7317 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7318 break;
7319 case OPC2_32_RRR1_MADDS_H_LL:
7320 CHECK_REG_PAIR(r4);
7321 CHECK_REG_PAIR(r3);
7322 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7323 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7324 break;
7325 case OPC2_32_RRR1_MADDS_H_LU:
7326 CHECK_REG_PAIR(r4);
7327 CHECK_REG_PAIR(r3);
7328 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7329 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7330 break;
7331 case OPC2_32_RRR1_MADDS_H_UL:
7332 CHECK_REG_PAIR(r4);
7333 CHECK_REG_PAIR(r3);
7334 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7335 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7336 break;
7337 case OPC2_32_RRR1_MADDS_H_UU:
7338 CHECK_REG_PAIR(r4);
7339 CHECK_REG_PAIR(r3);
7340 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7341 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7342 break;
7343 case OPC2_32_RRR1_MADDM_H_LL:
7344 CHECK_REG_PAIR(r4);
7345 CHECK_REG_PAIR(r3);
7346 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7347 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7348 break;
7349 case OPC2_32_RRR1_MADDM_H_LU:
7350 CHECK_REG_PAIR(r4);
7351 CHECK_REG_PAIR(r3);
7352 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7353 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7354 break;
7355 case OPC2_32_RRR1_MADDM_H_UL:
7356 CHECK_REG_PAIR(r4);
7357 CHECK_REG_PAIR(r3);
7358 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7359 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7360 break;
7361 case OPC2_32_RRR1_MADDM_H_UU:
7362 CHECK_REG_PAIR(r4);
7363 CHECK_REG_PAIR(r3);
7364 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7365 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7366 break;
7367 case OPC2_32_RRR1_MADDMS_H_LL:
7368 CHECK_REG_PAIR(r4);
7369 CHECK_REG_PAIR(r3);
7370 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7371 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7372 break;
7373 case OPC2_32_RRR1_MADDMS_H_LU:
7374 CHECK_REG_PAIR(r4);
7375 CHECK_REG_PAIR(r3);
7376 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7377 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7378 break;
7379 case OPC2_32_RRR1_MADDMS_H_UL:
7380 CHECK_REG_PAIR(r4);
7381 CHECK_REG_PAIR(r3);
7382 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7383 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7384 break;
7385 case OPC2_32_RRR1_MADDMS_H_UU:
7386 CHECK_REG_PAIR(r4);
7387 CHECK_REG_PAIR(r3);
7388 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7389 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7390 break;
7391 case OPC2_32_RRR1_MADDR_H_LL:
7392 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7393 cpu_gpr_d[r2], n, MODE_LL);
7394 break;
7395 case OPC2_32_RRR1_MADDR_H_LU:
7396 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7397 cpu_gpr_d[r2], n, MODE_LU);
7398 break;
7399 case OPC2_32_RRR1_MADDR_H_UL:
7400 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7401 cpu_gpr_d[r2], n, MODE_UL);
7402 break;
7403 case OPC2_32_RRR1_MADDR_H_UU:
7404 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7405 cpu_gpr_d[r2], n, MODE_UU);
7406 break;
7407 case OPC2_32_RRR1_MADDRS_H_LL:
7408 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7409 cpu_gpr_d[r2], n, MODE_LL);
7410 break;
7411 case OPC2_32_RRR1_MADDRS_H_LU:
7412 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7413 cpu_gpr_d[r2], n, MODE_LU);
7414 break;
7415 case OPC2_32_RRR1_MADDRS_H_UL:
7416 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7417 cpu_gpr_d[r2], n, MODE_UL);
7418 break;
7419 case OPC2_32_RRR1_MADDRS_H_UU:
7420 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7421 cpu_gpr_d[r2], n, MODE_UU);
7422 break;
7423 default:
7424 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7428 static void decode_rrr1_maddq_h(DisasContext *ctx)
7430 uint32_t op2;
7431 uint32_t r1, r2, r3, r4, n;
7432 TCGv temp, temp2;
7434 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7435 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7436 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7437 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7438 r4 = MASK_OP_RRR1_D(ctx->opcode);
7439 n = MASK_OP_RRR1_N(ctx->opcode);
7441 temp = tcg_const_i32(n);
7442 temp2 = tcg_temp_new();
7444 switch (op2) {
7445 case OPC2_32_RRR1_MADD_Q_32:
7446 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7447 cpu_gpr_d[r2], n, 32);
7448 break;
7449 case OPC2_32_RRR1_MADD_Q_64:
7450 CHECK_REG_PAIR(r4);
7451 CHECK_REG_PAIR(r3);
7452 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7453 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7455 break;
7456 case OPC2_32_RRR1_MADD_Q_32_L:
7457 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7458 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7459 temp, n, 16);
7460 break;
7461 case OPC2_32_RRR1_MADD_Q_64_L:
7462 CHECK_REG_PAIR(r4);
7463 CHECK_REG_PAIR(r3);
7464 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7465 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7466 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7468 break;
7469 case OPC2_32_RRR1_MADD_Q_32_U:
7470 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7471 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7472 temp, n, 16);
7473 break;
7474 case OPC2_32_RRR1_MADD_Q_64_U:
7475 CHECK_REG_PAIR(r4);
7476 CHECK_REG_PAIR(r3);
7477 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7478 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7479 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7481 break;
7482 case OPC2_32_RRR1_MADD_Q_32_LL:
7483 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7484 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7485 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7486 break;
7487 case OPC2_32_RRR1_MADD_Q_64_LL:
7488 CHECK_REG_PAIR(r4);
7489 CHECK_REG_PAIR(r3);
7490 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7491 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7492 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7493 cpu_gpr_d[r3+1], temp, temp2, n);
7494 break;
7495 case OPC2_32_RRR1_MADD_Q_32_UU:
7496 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7497 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7498 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7499 break;
7500 case OPC2_32_RRR1_MADD_Q_64_UU:
7501 CHECK_REG_PAIR(r4);
7502 CHECK_REG_PAIR(r3);
7503 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7504 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7505 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7506 cpu_gpr_d[r3+1], temp, temp2, n);
7507 break;
7508 case OPC2_32_RRR1_MADDS_Q_32:
7509 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7510 cpu_gpr_d[r2], n, 32);
7511 break;
7512 case OPC2_32_RRR1_MADDS_Q_64:
7513 CHECK_REG_PAIR(r4);
7514 CHECK_REG_PAIR(r3);
7515 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7516 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7518 break;
7519 case OPC2_32_RRR1_MADDS_Q_32_L:
7520 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7521 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7522 temp, n, 16);
7523 break;
7524 case OPC2_32_RRR1_MADDS_Q_64_L:
7525 CHECK_REG_PAIR(r4);
7526 CHECK_REG_PAIR(r3);
7527 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7528 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7529 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7531 break;
7532 case OPC2_32_RRR1_MADDS_Q_32_U:
7533 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7534 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7535 temp, n, 16);
7536 break;
7537 case OPC2_32_RRR1_MADDS_Q_64_U:
7538 CHECK_REG_PAIR(r4);
7539 CHECK_REG_PAIR(r3);
7540 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7541 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7542 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7544 break;
7545 case OPC2_32_RRR1_MADDS_Q_32_LL:
7546 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7547 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7548 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7549 break;
7550 case OPC2_32_RRR1_MADDS_Q_64_LL:
7551 CHECK_REG_PAIR(r4);
7552 CHECK_REG_PAIR(r3);
7553 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7554 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7555 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7556 cpu_gpr_d[r3+1], temp, temp2, n);
7557 break;
7558 case OPC2_32_RRR1_MADDS_Q_32_UU:
7559 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7560 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7561 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7562 break;
7563 case OPC2_32_RRR1_MADDS_Q_64_UU:
7564 CHECK_REG_PAIR(r4);
7565 CHECK_REG_PAIR(r3);
7566 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7567 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7568 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7569 cpu_gpr_d[r3+1], temp, temp2, n);
7570 break;
7571 case OPC2_32_RRR1_MADDR_H_64_UL:
7572 CHECK_REG_PAIR(r3);
7573 gen_maddr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7574 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7575 break;
7576 case OPC2_32_RRR1_MADDRS_H_64_UL:
7577 CHECK_REG_PAIR(r3);
7578 gen_maddr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7579 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7580 break;
7581 case OPC2_32_RRR1_MADDR_Q_32_LL:
7582 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7583 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7584 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7585 break;
7586 case OPC2_32_RRR1_MADDR_Q_32_UU:
7587 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7588 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7589 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7590 break;
7591 case OPC2_32_RRR1_MADDRS_Q_32_LL:
7592 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7593 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7594 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7595 break;
7596 case OPC2_32_RRR1_MADDRS_Q_32_UU:
7597 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7598 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7599 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7600 break;
7601 default:
7602 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7604 tcg_temp_free(temp);
7605 tcg_temp_free(temp2);
7608 static void decode_rrr1_maddsu_h(DisasContext *ctx)
7610 uint32_t op2;
7611 uint32_t r1, r2, r3, r4, n;
7613 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7614 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7615 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7616 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7617 r4 = MASK_OP_RRR1_D(ctx->opcode);
7618 n = MASK_OP_RRR1_N(ctx->opcode);
7620 switch (op2) {
7621 case OPC2_32_RRR1_MADDSU_H_32_LL:
7622 CHECK_REG_PAIR(r4);
7623 CHECK_REG_PAIR(r3);
7624 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7625 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7626 break;
7627 case OPC2_32_RRR1_MADDSU_H_32_LU:
7628 CHECK_REG_PAIR(r4);
7629 CHECK_REG_PAIR(r3);
7630 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7631 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7632 break;
7633 case OPC2_32_RRR1_MADDSU_H_32_UL:
7634 CHECK_REG_PAIR(r4);
7635 CHECK_REG_PAIR(r3);
7636 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7637 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7638 break;
7639 case OPC2_32_RRR1_MADDSU_H_32_UU:
7640 CHECK_REG_PAIR(r4);
7641 CHECK_REG_PAIR(r3);
7642 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7643 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7644 break;
7645 case OPC2_32_RRR1_MADDSUS_H_32_LL:
7646 CHECK_REG_PAIR(r4);
7647 CHECK_REG_PAIR(r3);
7648 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7649 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7650 n, MODE_LL);
7651 break;
7652 case OPC2_32_RRR1_MADDSUS_H_32_LU:
7653 CHECK_REG_PAIR(r4);
7654 CHECK_REG_PAIR(r3);
7655 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7656 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7657 n, MODE_LU);
7658 break;
7659 case OPC2_32_RRR1_MADDSUS_H_32_UL:
7660 CHECK_REG_PAIR(r4);
7661 CHECK_REG_PAIR(r3);
7662 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7663 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7664 n, MODE_UL);
7665 break;
7666 case OPC2_32_RRR1_MADDSUS_H_32_UU:
7667 CHECK_REG_PAIR(r4);
7668 CHECK_REG_PAIR(r3);
7669 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7670 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7671 n, MODE_UU);
7672 break;
7673 case OPC2_32_RRR1_MADDSUM_H_64_LL:
7674 CHECK_REG_PAIR(r4);
7675 CHECK_REG_PAIR(r3);
7676 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7677 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7678 n, MODE_LL);
7679 break;
7680 case OPC2_32_RRR1_MADDSUM_H_64_LU:
7681 CHECK_REG_PAIR(r4);
7682 CHECK_REG_PAIR(r3);
7683 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7684 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7685 n, MODE_LU);
7686 break;
7687 case OPC2_32_RRR1_MADDSUM_H_64_UL:
7688 CHECK_REG_PAIR(r4);
7689 CHECK_REG_PAIR(r3);
7690 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7691 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7692 n, MODE_UL);
7693 break;
7694 case OPC2_32_RRR1_MADDSUM_H_64_UU:
7695 CHECK_REG_PAIR(r4);
7696 CHECK_REG_PAIR(r3);
7697 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7698 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7699 n, MODE_UU);
7700 break;
7701 case OPC2_32_RRR1_MADDSUMS_H_64_LL:
7702 CHECK_REG_PAIR(r4);
7703 CHECK_REG_PAIR(r3);
7704 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7705 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7706 n, MODE_LL);
7707 break;
7708 case OPC2_32_RRR1_MADDSUMS_H_64_LU:
7709 CHECK_REG_PAIR(r4);
7710 CHECK_REG_PAIR(r3);
7711 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7712 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7713 n, MODE_LU);
7714 break;
7715 case OPC2_32_RRR1_MADDSUMS_H_64_UL:
7716 CHECK_REG_PAIR(r4);
7717 CHECK_REG_PAIR(r3);
7718 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7719 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7720 n, MODE_UL);
7721 break;
7722 case OPC2_32_RRR1_MADDSUMS_H_64_UU:
7723 CHECK_REG_PAIR(r4);
7724 CHECK_REG_PAIR(r3);
7725 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7726 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7727 n, MODE_UU);
7728 break;
7729 case OPC2_32_RRR1_MADDSUR_H_16_LL:
7730 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7731 cpu_gpr_d[r2], n, MODE_LL);
7732 break;
7733 case OPC2_32_RRR1_MADDSUR_H_16_LU:
7734 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7735 cpu_gpr_d[r2], n, MODE_LU);
7736 break;
7737 case OPC2_32_RRR1_MADDSUR_H_16_UL:
7738 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7739 cpu_gpr_d[r2], n, MODE_UL);
7740 break;
7741 case OPC2_32_RRR1_MADDSUR_H_16_UU:
7742 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7743 cpu_gpr_d[r2], n, MODE_UU);
7744 break;
7745 case OPC2_32_RRR1_MADDSURS_H_16_LL:
7746 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7747 cpu_gpr_d[r2], n, MODE_LL);
7748 break;
7749 case OPC2_32_RRR1_MADDSURS_H_16_LU:
7750 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7751 cpu_gpr_d[r2], n, MODE_LU);
7752 break;
7753 case OPC2_32_RRR1_MADDSURS_H_16_UL:
7754 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7755 cpu_gpr_d[r2], n, MODE_UL);
7756 break;
7757 case OPC2_32_RRR1_MADDSURS_H_16_UU:
7758 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7759 cpu_gpr_d[r2], n, MODE_UU);
7760 break;
7761 default:
7762 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7766 static void decode_rrr1_msub(DisasContext *ctx)
7768 uint32_t op2;
7769 uint32_t r1, r2, r3, r4, n;
7771 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7772 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7773 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7774 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7775 r4 = MASK_OP_RRR1_D(ctx->opcode);
7776 n = MASK_OP_RRR1_N(ctx->opcode);
7778 switch (op2) {
7779 case OPC2_32_RRR1_MSUB_H_LL:
7780 CHECK_REG_PAIR(r4);
7781 CHECK_REG_PAIR(r3);
7782 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7783 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7784 break;
7785 case OPC2_32_RRR1_MSUB_H_LU:
7786 CHECK_REG_PAIR(r4);
7787 CHECK_REG_PAIR(r3);
7788 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7789 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7790 break;
7791 case OPC2_32_RRR1_MSUB_H_UL:
7792 CHECK_REG_PAIR(r4);
7793 CHECK_REG_PAIR(r3);
7794 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7795 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7796 break;
7797 case OPC2_32_RRR1_MSUB_H_UU:
7798 CHECK_REG_PAIR(r4);
7799 CHECK_REG_PAIR(r3);
7800 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7801 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7802 break;
7803 case OPC2_32_RRR1_MSUBS_H_LL:
7804 CHECK_REG_PAIR(r4);
7805 CHECK_REG_PAIR(r3);
7806 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7807 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7808 break;
7809 case OPC2_32_RRR1_MSUBS_H_LU:
7810 CHECK_REG_PAIR(r4);
7811 CHECK_REG_PAIR(r3);
7812 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7813 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7814 break;
7815 case OPC2_32_RRR1_MSUBS_H_UL:
7816 CHECK_REG_PAIR(r4);
7817 CHECK_REG_PAIR(r3);
7818 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7819 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7820 break;
7821 case OPC2_32_RRR1_MSUBS_H_UU:
7822 CHECK_REG_PAIR(r4);
7823 CHECK_REG_PAIR(r3);
7824 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7825 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7826 break;
7827 case OPC2_32_RRR1_MSUBM_H_LL:
7828 CHECK_REG_PAIR(r4);
7829 CHECK_REG_PAIR(r3);
7830 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7831 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7832 break;
7833 case OPC2_32_RRR1_MSUBM_H_LU:
7834 CHECK_REG_PAIR(r4);
7835 CHECK_REG_PAIR(r3);
7836 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7837 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7838 break;
7839 case OPC2_32_RRR1_MSUBM_H_UL:
7840 CHECK_REG_PAIR(r4);
7841 CHECK_REG_PAIR(r3);
7842 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7843 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7844 break;
7845 case OPC2_32_RRR1_MSUBM_H_UU:
7846 CHECK_REG_PAIR(r4);
7847 CHECK_REG_PAIR(r3);
7848 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7849 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7850 break;
7851 case OPC2_32_RRR1_MSUBMS_H_LL:
7852 CHECK_REG_PAIR(r4);
7853 CHECK_REG_PAIR(r3);
7854 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7855 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7856 break;
7857 case OPC2_32_RRR1_MSUBMS_H_LU:
7858 CHECK_REG_PAIR(r4);
7859 CHECK_REG_PAIR(r3);
7860 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7861 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7862 break;
7863 case OPC2_32_RRR1_MSUBMS_H_UL:
7864 CHECK_REG_PAIR(r4);
7865 CHECK_REG_PAIR(r3);
7866 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7867 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7868 break;
7869 case OPC2_32_RRR1_MSUBMS_H_UU:
7870 CHECK_REG_PAIR(r4);
7871 CHECK_REG_PAIR(r3);
7872 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7873 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7874 break;
7875 case OPC2_32_RRR1_MSUBR_H_LL:
7876 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7877 cpu_gpr_d[r2], n, MODE_LL);
7878 break;
7879 case OPC2_32_RRR1_MSUBR_H_LU:
7880 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7881 cpu_gpr_d[r2], n, MODE_LU);
7882 break;
7883 case OPC2_32_RRR1_MSUBR_H_UL:
7884 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7885 cpu_gpr_d[r2], n, MODE_UL);
7886 break;
7887 case OPC2_32_RRR1_MSUBR_H_UU:
7888 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7889 cpu_gpr_d[r2], n, MODE_UU);
7890 break;
7891 case OPC2_32_RRR1_MSUBRS_H_LL:
7892 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7893 cpu_gpr_d[r2], n, MODE_LL);
7894 break;
7895 case OPC2_32_RRR1_MSUBRS_H_LU:
7896 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7897 cpu_gpr_d[r2], n, MODE_LU);
7898 break;
7899 case OPC2_32_RRR1_MSUBRS_H_UL:
7900 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7901 cpu_gpr_d[r2], n, MODE_UL);
7902 break;
7903 case OPC2_32_RRR1_MSUBRS_H_UU:
7904 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7905 cpu_gpr_d[r2], n, MODE_UU);
7906 break;
7907 default:
7908 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7912 static void decode_rrr1_msubq_h(DisasContext *ctx)
7914 uint32_t op2;
7915 uint32_t r1, r2, r3, r4, n;
7916 TCGv temp, temp2;
7918 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7919 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7920 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7921 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7922 r4 = MASK_OP_RRR1_D(ctx->opcode);
7923 n = MASK_OP_RRR1_N(ctx->opcode);
7925 temp = tcg_const_i32(n);
7926 temp2 = tcg_temp_new();
7928 switch (op2) {
7929 case OPC2_32_RRR1_MSUB_Q_32:
7930 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7931 cpu_gpr_d[r2], n, 32);
7932 break;
7933 case OPC2_32_RRR1_MSUB_Q_64:
7934 CHECK_REG_PAIR(r4);
7935 CHECK_REG_PAIR(r3);
7936 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7937 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7939 break;
7940 case OPC2_32_RRR1_MSUB_Q_32_L:
7941 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7942 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7943 temp, n, 16);
7944 break;
7945 case OPC2_32_RRR1_MSUB_Q_64_L:
7946 CHECK_REG_PAIR(r4);
7947 CHECK_REG_PAIR(r3);
7948 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7949 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7950 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7952 break;
7953 case OPC2_32_RRR1_MSUB_Q_32_U:
7954 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7955 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7956 temp, n, 16);
7957 break;
7958 case OPC2_32_RRR1_MSUB_Q_64_U:
7959 CHECK_REG_PAIR(r4);
7960 CHECK_REG_PAIR(r3);
7961 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7962 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7963 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7965 break;
7966 case OPC2_32_RRR1_MSUB_Q_32_LL:
7967 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7968 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7969 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7970 break;
7971 case OPC2_32_RRR1_MSUB_Q_64_LL:
7972 CHECK_REG_PAIR(r4);
7973 CHECK_REG_PAIR(r3);
7974 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7975 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7976 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7977 cpu_gpr_d[r3+1], temp, temp2, n);
7978 break;
7979 case OPC2_32_RRR1_MSUB_Q_32_UU:
7980 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7981 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7982 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7983 break;
7984 case OPC2_32_RRR1_MSUB_Q_64_UU:
7985 CHECK_REG_PAIR(r4);
7986 CHECK_REG_PAIR(r3);
7987 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7988 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7989 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7990 cpu_gpr_d[r3+1], temp, temp2, n);
7991 break;
7992 case OPC2_32_RRR1_MSUBS_Q_32:
7993 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7994 cpu_gpr_d[r2], n, 32);
7995 break;
7996 case OPC2_32_RRR1_MSUBS_Q_64:
7997 CHECK_REG_PAIR(r4);
7998 CHECK_REG_PAIR(r3);
7999 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8000 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8002 break;
8003 case OPC2_32_RRR1_MSUBS_Q_32_L:
8004 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
8005 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8006 temp, n, 16);
8007 break;
8008 case OPC2_32_RRR1_MSUBS_Q_64_L:
8009 CHECK_REG_PAIR(r4);
8010 CHECK_REG_PAIR(r3);
8011 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
8012 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8013 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
8015 break;
8016 case OPC2_32_RRR1_MSUBS_Q_32_U:
8017 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
8018 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8019 temp, n, 16);
8020 break;
8021 case OPC2_32_RRR1_MSUBS_Q_64_U:
8022 CHECK_REG_PAIR(r4);
8023 CHECK_REG_PAIR(r3);
8024 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
8025 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8026 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
8028 break;
8029 case OPC2_32_RRR1_MSUBS_Q_32_LL:
8030 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8031 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8032 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8033 break;
8034 case OPC2_32_RRR1_MSUBS_Q_64_LL:
8035 CHECK_REG_PAIR(r4);
8036 CHECK_REG_PAIR(r3);
8037 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8038 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8039 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8040 cpu_gpr_d[r3+1], temp, temp2, n);
8041 break;
8042 case OPC2_32_RRR1_MSUBS_Q_32_UU:
8043 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8044 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8045 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8046 break;
8047 case OPC2_32_RRR1_MSUBS_Q_64_UU:
8048 CHECK_REG_PAIR(r4);
8049 CHECK_REG_PAIR(r3);
8050 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8051 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8052 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8053 cpu_gpr_d[r3+1], temp, temp2, n);
8054 break;
8055 case OPC2_32_RRR1_MSUBR_H_64_UL:
8056 CHECK_REG_PAIR(r3);
8057 gen_msubr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
8058 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
8059 break;
8060 case OPC2_32_RRR1_MSUBRS_H_64_UL:
8061 CHECK_REG_PAIR(r3);
8062 gen_msubr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
8063 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
8064 break;
8065 case OPC2_32_RRR1_MSUBR_Q_32_LL:
8066 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8067 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8068 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8069 break;
8070 case OPC2_32_RRR1_MSUBR_Q_32_UU:
8071 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8072 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8073 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8074 break;
8075 case OPC2_32_RRR1_MSUBRS_Q_32_LL:
8076 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8077 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8078 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8079 break;
8080 case OPC2_32_RRR1_MSUBRS_Q_32_UU:
8081 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8082 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8083 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8084 break;
8085 default:
8086 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8088 tcg_temp_free(temp);
8089 tcg_temp_free(temp2);
8092 static void decode_rrr1_msubad_h(DisasContext *ctx)
8094 uint32_t op2;
8095 uint32_t r1, r2, r3, r4, n;
8097 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
8098 r1 = MASK_OP_RRR1_S1(ctx->opcode);
8099 r2 = MASK_OP_RRR1_S2(ctx->opcode);
8100 r3 = MASK_OP_RRR1_S3(ctx->opcode);
8101 r4 = MASK_OP_RRR1_D(ctx->opcode);
8102 n = MASK_OP_RRR1_N(ctx->opcode);
8104 switch (op2) {
8105 case OPC2_32_RRR1_MSUBAD_H_32_LL:
8106 CHECK_REG_PAIR(r4);
8107 CHECK_REG_PAIR(r3);
8108 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8109 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
8110 break;
8111 case OPC2_32_RRR1_MSUBAD_H_32_LU:
8112 CHECK_REG_PAIR(r4);
8113 CHECK_REG_PAIR(r3);
8114 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8115 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
8116 break;
8117 case OPC2_32_RRR1_MSUBAD_H_32_UL:
8118 CHECK_REG_PAIR(r4);
8119 CHECK_REG_PAIR(r3);
8120 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8121 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
8122 break;
8123 case OPC2_32_RRR1_MSUBAD_H_32_UU:
8124 CHECK_REG_PAIR(r4);
8125 CHECK_REG_PAIR(r3);
8126 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8127 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
8128 break;
8129 case OPC2_32_RRR1_MSUBADS_H_32_LL:
8130 CHECK_REG_PAIR(r4);
8131 CHECK_REG_PAIR(r3);
8132 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8133 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8134 n, MODE_LL);
8135 break;
8136 case OPC2_32_RRR1_MSUBADS_H_32_LU:
8137 CHECK_REG_PAIR(r4);
8138 CHECK_REG_PAIR(r3);
8139 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8140 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8141 n, MODE_LU);
8142 break;
8143 case OPC2_32_RRR1_MSUBADS_H_32_UL:
8144 CHECK_REG_PAIR(r4);
8145 CHECK_REG_PAIR(r3);
8146 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8147 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8148 n, MODE_UL);
8149 break;
8150 case OPC2_32_RRR1_MSUBADS_H_32_UU:
8151 CHECK_REG_PAIR(r4);
8152 CHECK_REG_PAIR(r3);
8153 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8154 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8155 n, MODE_UU);
8156 break;
8157 case OPC2_32_RRR1_MSUBADM_H_64_LL:
8158 CHECK_REG_PAIR(r4);
8159 CHECK_REG_PAIR(r3);
8160 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8161 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8162 n, MODE_LL);
8163 break;
8164 case OPC2_32_RRR1_MSUBADM_H_64_LU:
8165 CHECK_REG_PAIR(r4);
8166 CHECK_REG_PAIR(r3);
8167 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8168 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8169 n, MODE_LU);
8170 break;
8171 case OPC2_32_RRR1_MSUBADM_H_64_UL:
8172 CHECK_REG_PAIR(r4);
8173 CHECK_REG_PAIR(r3);
8174 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8175 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8176 n, MODE_UL);
8177 break;
8178 case OPC2_32_RRR1_MSUBADM_H_64_UU:
8179 CHECK_REG_PAIR(r4);
8180 CHECK_REG_PAIR(r3);
8181 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8182 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8183 n, MODE_UU);
8184 break;
8185 case OPC2_32_RRR1_MSUBADMS_H_64_LL:
8186 CHECK_REG_PAIR(r4);
8187 CHECK_REG_PAIR(r3);
8188 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8189 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8190 n, MODE_LL);
8191 break;
8192 case OPC2_32_RRR1_MSUBADMS_H_64_LU:
8193 CHECK_REG_PAIR(r4);
8194 CHECK_REG_PAIR(r3);
8195 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8196 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8197 n, MODE_LU);
8198 break;
8199 case OPC2_32_RRR1_MSUBADMS_H_64_UL:
8200 CHECK_REG_PAIR(r4);
8201 CHECK_REG_PAIR(r3);
8202 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8203 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8204 n, MODE_UL);
8205 break;
8206 case OPC2_32_RRR1_MSUBADMS_H_64_UU:
8207 CHECK_REG_PAIR(r4);
8208 CHECK_REG_PAIR(r3);
8209 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8210 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8211 n, MODE_UU);
8212 break;
8213 case OPC2_32_RRR1_MSUBADR_H_16_LL:
8214 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8215 cpu_gpr_d[r2], n, MODE_LL);
8216 break;
8217 case OPC2_32_RRR1_MSUBADR_H_16_LU:
8218 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8219 cpu_gpr_d[r2], n, MODE_LU);
8220 break;
8221 case OPC2_32_RRR1_MSUBADR_H_16_UL:
8222 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8223 cpu_gpr_d[r2], n, MODE_UL);
8224 break;
8225 case OPC2_32_RRR1_MSUBADR_H_16_UU:
8226 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8227 cpu_gpr_d[r2], n, MODE_UU);
8228 break;
8229 case OPC2_32_RRR1_MSUBADRS_H_16_LL:
8230 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8231 cpu_gpr_d[r2], n, MODE_LL);
8232 break;
8233 case OPC2_32_RRR1_MSUBADRS_H_16_LU:
8234 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8235 cpu_gpr_d[r2], n, MODE_LU);
8236 break;
8237 case OPC2_32_RRR1_MSUBADRS_H_16_UL:
8238 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8239 cpu_gpr_d[r2], n, MODE_UL);
8240 break;
8241 case OPC2_32_RRR1_MSUBADRS_H_16_UU:
8242 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8243 cpu_gpr_d[r2], n, MODE_UU);
8244 break;
8245 default:
8246 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8250 /* RRRR format */
8251 static void decode_rrrr_extract_insert(DisasContext *ctx)
8253 uint32_t op2;
8254 int r1, r2, r3, r4;
8255 TCGv tmp_width, tmp_pos;
8257 r1 = MASK_OP_RRRR_S1(ctx->opcode);
8258 r2 = MASK_OP_RRRR_S2(ctx->opcode);
8259 r3 = MASK_OP_RRRR_S3(ctx->opcode);
8260 r4 = MASK_OP_RRRR_D(ctx->opcode);
8261 op2 = MASK_OP_RRRR_OP2(ctx->opcode);
8263 tmp_pos = tcg_temp_new();
8264 tmp_width = tcg_temp_new();
8266 switch (op2) {
8267 case OPC2_32_RRRR_DEXTR:
8268 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8269 if (r1 == r2) {
8270 tcg_gen_rotl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
8271 } else {
8272 tcg_gen_shl_tl(tmp_width, cpu_gpr_d[r1], tmp_pos);
8273 tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
8274 tcg_gen_shr_tl(tmp_pos, cpu_gpr_d[r2], tmp_pos);
8275 tcg_gen_or_tl(cpu_gpr_d[r4], tmp_width, tmp_pos);
8277 break;
8278 case OPC2_32_RRRR_EXTR:
8279 case OPC2_32_RRRR_EXTR_U:
8280 CHECK_REG_PAIR(r3);
8281 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
8282 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8283 tcg_gen_add_tl(tmp_pos, tmp_pos, tmp_width);
8284 tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
8285 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
8286 tcg_gen_subfi_tl(tmp_width, 32, tmp_width);
8287 if (op2 == OPC2_32_RRRR_EXTR) {
8288 tcg_gen_sar_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
8289 } else {
8290 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
8292 break;
8293 case OPC2_32_RRRR_INSERT:
8294 CHECK_REG_PAIR(r3);
8295 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
8296 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8297 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], tmp_width,
8298 tmp_pos);
8299 break;
8300 default:
8301 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8303 tcg_temp_free(tmp_pos);
8304 tcg_temp_free(tmp_width);
8307 /* RRRW format */
8308 static void decode_rrrw_extract_insert(DisasContext *ctx)
8310 uint32_t op2;
8311 int r1, r2, r3, r4;
8312 int32_t width;
8314 TCGv temp, temp2;
8316 op2 = MASK_OP_RRRW_OP2(ctx->opcode);
8317 r1 = MASK_OP_RRRW_S1(ctx->opcode);
8318 r2 = MASK_OP_RRRW_S2(ctx->opcode);
8319 r3 = MASK_OP_RRRW_S3(ctx->opcode);
8320 r4 = MASK_OP_RRRW_D(ctx->opcode);
8321 width = MASK_OP_RRRW_WIDTH(ctx->opcode);
8323 temp = tcg_temp_new();
8325 switch (op2) {
8326 case OPC2_32_RRRW_EXTR:
8327 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8328 tcg_gen_addi_tl(temp, temp, width);
8329 tcg_gen_subfi_tl(temp, 32, temp);
8330 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
8331 tcg_gen_sari_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], 32 - width);
8332 break;
8333 case OPC2_32_RRRW_EXTR_U:
8334 if (width == 0) {
8335 tcg_gen_movi_tl(cpu_gpr_d[r4], 0);
8336 } else {
8337 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8338 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
8339 tcg_gen_andi_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], ~0u >> (32-width));
8341 break;
8342 case OPC2_32_RRRW_IMASK:
8343 temp2 = tcg_temp_new();
8345 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8346 tcg_gen_movi_tl(temp2, (1 << width) - 1);
8347 tcg_gen_shl_tl(temp2, temp2, temp);
8348 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r2], temp);
8349 tcg_gen_mov_tl(cpu_gpr_d[r4+1], temp2);
8351 tcg_temp_free(temp2);
8352 break;
8353 case OPC2_32_RRRW_INSERT:
8354 temp2 = tcg_temp_new();
8356 tcg_gen_movi_tl(temp, width);
8357 tcg_gen_andi_tl(temp2, cpu_gpr_d[r3], 0x1f);
8358 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], temp, temp2);
8360 tcg_temp_free(temp2);
8361 break;
8362 default:
8363 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8365 tcg_temp_free(temp);
8368 /* SYS Format*/
8369 static void decode_sys_interrupts(DisasContext *ctx)
8371 uint32_t op2;
8372 uint32_t r1;
8373 TCGLabel *l1;
8374 TCGv tmp;
8376 op2 = MASK_OP_SYS_OP2(ctx->opcode);
8377 r1 = MASK_OP_SYS_S1D(ctx->opcode);
8379 switch (op2) {
8380 case OPC2_32_SYS_DEBUG:
8381 /* raise EXCP_DEBUG */
8382 break;
8383 case OPC2_32_SYS_DISABLE:
8384 tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~MASK_ICR_IE_1_3);
8385 break;
8386 case OPC2_32_SYS_DSYNC:
8387 break;
8388 case OPC2_32_SYS_ENABLE:
8389 tcg_gen_ori_tl(cpu_ICR, cpu_ICR, MASK_ICR_IE_1_3);
8390 break;
8391 case OPC2_32_SYS_ISYNC:
8392 break;
8393 case OPC2_32_SYS_NOP:
8394 break;
8395 case OPC2_32_SYS_RET:
8396 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
8397 break;
8398 case OPC2_32_SYS_FRET:
8399 gen_fret(ctx);
8400 break;
8401 case OPC2_32_SYS_RFE:
8402 gen_helper_rfe(cpu_env);
8403 tcg_gen_exit_tb(NULL, 0);
8404 ctx->base.is_jmp = DISAS_NORETURN;
8405 break;
8406 case OPC2_32_SYS_RFM:
8407 if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
8408 tmp = tcg_temp_new();
8409 l1 = gen_new_label();
8411 tcg_gen_ld32u_tl(tmp, cpu_env, offsetof(CPUTriCoreState, DBGSR));
8412 tcg_gen_andi_tl(tmp, tmp, MASK_DBGSR_DE);
8413 tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1);
8414 gen_helper_rfm(cpu_env);
8415 gen_set_label(l1);
8416 tcg_gen_exit_tb(NULL, 0);
8417 ctx->base.is_jmp = DISAS_NORETURN;
8418 tcg_temp_free(tmp);
8419 } else {
8420 /* generate privilege trap */
8422 break;
8423 case OPC2_32_SYS_RSLCX:
8424 gen_helper_rslcx(cpu_env);
8425 break;
8426 case OPC2_32_SYS_SVLCX:
8427 gen_helper_svlcx(cpu_env);
8428 break;
8429 case OPC2_32_SYS_RESTORE:
8430 if (has_feature(ctx, TRICORE_FEATURE_16)) {
8431 if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
8432 (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
8433 tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
8434 } /* else raise privilege trap */
8435 } else {
8436 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8438 break;
8439 case OPC2_32_SYS_TRAPSV:
8440 l1 = gen_new_label();
8441 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_SV, 0, l1);
8442 generate_trap(ctx, TRAPC_ASSERT, TIN5_SOVF);
8443 gen_set_label(l1);
8444 break;
8445 case OPC2_32_SYS_TRAPV:
8446 l1 = gen_new_label();
8447 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_V, 0, l1);
8448 generate_trap(ctx, TRAPC_ASSERT, TIN5_OVF);
8449 gen_set_label(l1);
8450 break;
8451 default:
8452 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8456 static void decode_32Bit_opc(DisasContext *ctx)
8458 int op1;
8459 int32_t r1, r2, r3;
8460 int32_t address, const16;
8461 int8_t b, const4;
8462 int32_t bpos;
8463 TCGv temp, temp2, temp3;
8465 op1 = MASK_OP_MAJOR(ctx->opcode);
8467 /* handle JNZ.T opcode only being 7 bit long */
8468 if (unlikely((op1 & 0x7f) == OPCM_32_BRN_JTT)) {
8469 op1 = OPCM_32_BRN_JTT;
8472 switch (op1) {
8473 /* ABS-format */
8474 case OPCM_32_ABS_LDW:
8475 decode_abs_ldw(ctx);
8476 break;
8477 case OPCM_32_ABS_LDB:
8478 decode_abs_ldb(ctx);
8479 break;
8480 case OPCM_32_ABS_LDMST_SWAP:
8481 decode_abs_ldst_swap(ctx);
8482 break;
8483 case OPCM_32_ABS_LDST_CONTEXT:
8484 decode_abs_ldst_context(ctx);
8485 break;
8486 case OPCM_32_ABS_STORE:
8487 decode_abs_store(ctx);
8488 break;
8489 case OPCM_32_ABS_STOREB_H:
8490 decode_abs_storeb_h(ctx);
8491 break;
8492 case OPC1_32_ABS_STOREQ:
8493 address = MASK_OP_ABS_OFF18(ctx->opcode);
8494 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8495 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8496 temp2 = tcg_temp_new();
8498 tcg_gen_shri_tl(temp2, cpu_gpr_d[r1], 16);
8499 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_LEUW);
8501 tcg_temp_free(temp2);
8502 tcg_temp_free(temp);
8503 break;
8504 case OPC1_32_ABS_LD_Q:
8505 address = MASK_OP_ABS_OFF18(ctx->opcode);
8506 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8507 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8509 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
8510 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
8512 tcg_temp_free(temp);
8513 break;
8514 case OPC1_32_ABS_LEA:
8515 address = MASK_OP_ABS_OFF18(ctx->opcode);
8516 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8517 tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address));
8518 break;
8519 /* ABSB-format */
8520 case OPC1_32_ABSB_ST_T:
8521 address = MASK_OP_ABS_OFF18(ctx->opcode);
8522 b = MASK_OP_ABSB_B(ctx->opcode);
8523 bpos = MASK_OP_ABSB_BPOS(ctx->opcode);
8525 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8526 temp2 = tcg_temp_new();
8528 tcg_gen_qemu_ld_tl(temp2, temp, ctx->mem_idx, MO_UB);
8529 tcg_gen_andi_tl(temp2, temp2, ~(0x1u << bpos));
8530 tcg_gen_ori_tl(temp2, temp2, (b << bpos));
8531 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_UB);
8533 tcg_temp_free(temp);
8534 tcg_temp_free(temp2);
8535 break;
8536 /* B-format */
8537 case OPC1_32_B_CALL:
8538 case OPC1_32_B_CALLA:
8539 case OPC1_32_B_FCALL:
8540 case OPC1_32_B_FCALLA:
8541 case OPC1_32_B_J:
8542 case OPC1_32_B_JA:
8543 case OPC1_32_B_JL:
8544 case OPC1_32_B_JLA:
8545 address = MASK_OP_B_DISP24_SEXT(ctx->opcode);
8546 gen_compute_branch(ctx, op1, 0, 0, 0, address);
8547 break;
8548 /* Bit-format */
8549 case OPCM_32_BIT_ANDACC:
8550 decode_bit_andacc(ctx);
8551 break;
8552 case OPCM_32_BIT_LOGICAL_T1:
8553 decode_bit_logical_t(ctx);
8554 break;
8555 case OPCM_32_BIT_INSERT:
8556 decode_bit_insert(ctx);
8557 break;
8558 case OPCM_32_BIT_LOGICAL_T2:
8559 decode_bit_logical_t2(ctx);
8560 break;
8561 case OPCM_32_BIT_ORAND:
8562 decode_bit_orand(ctx);
8563 break;
8564 case OPCM_32_BIT_SH_LOGIC1:
8565 decode_bit_sh_logic1(ctx);
8566 break;
8567 case OPCM_32_BIT_SH_LOGIC2:
8568 decode_bit_sh_logic2(ctx);
8569 break;
8570 /* BO Format */
8571 case OPCM_32_BO_ADDRMODE_POST_PRE_BASE:
8572 decode_bo_addrmode_post_pre_base(ctx);
8573 break;
8574 case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR:
8575 decode_bo_addrmode_bitreverse_circular(ctx);
8576 break;
8577 case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE:
8578 decode_bo_addrmode_ld_post_pre_base(ctx);
8579 break;
8580 case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR:
8581 decode_bo_addrmode_ld_bitreverse_circular(ctx);
8582 break;
8583 case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE:
8584 decode_bo_addrmode_stctx_post_pre_base(ctx);
8585 break;
8586 case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
8587 decode_bo_addrmode_ldmst_bitreverse_circular(ctx);
8588 break;
8589 /* BOL-format */
8590 case OPC1_32_BOL_LD_A_LONGOFF:
8591 case OPC1_32_BOL_LD_W_LONGOFF:
8592 case OPC1_32_BOL_LEA_LONGOFF:
8593 case OPC1_32_BOL_ST_W_LONGOFF:
8594 case OPC1_32_BOL_ST_A_LONGOFF:
8595 case OPC1_32_BOL_LD_B_LONGOFF:
8596 case OPC1_32_BOL_LD_BU_LONGOFF:
8597 case OPC1_32_BOL_LD_H_LONGOFF:
8598 case OPC1_32_BOL_LD_HU_LONGOFF:
8599 case OPC1_32_BOL_ST_B_LONGOFF:
8600 case OPC1_32_BOL_ST_H_LONGOFF:
8601 decode_bol_opc(ctx, op1);
8602 break;
8603 /* BRC Format */
8604 case OPCM_32_BRC_EQ_NEQ:
8605 case OPCM_32_BRC_GE:
8606 case OPCM_32_BRC_JLT:
8607 case OPCM_32_BRC_JNE:
8608 const4 = MASK_OP_BRC_CONST4_SEXT(ctx->opcode);
8609 address = MASK_OP_BRC_DISP15_SEXT(ctx->opcode);
8610 r1 = MASK_OP_BRC_S1(ctx->opcode);
8611 gen_compute_branch(ctx, op1, r1, 0, const4, address);
8612 break;
8613 /* BRN Format */
8614 case OPCM_32_BRN_JTT:
8615 address = MASK_OP_BRN_DISP15_SEXT(ctx->opcode);
8616 r1 = MASK_OP_BRN_S1(ctx->opcode);
8617 gen_compute_branch(ctx, op1, r1, 0, 0, address);
8618 break;
8619 /* BRR Format */
8620 case OPCM_32_BRR_EQ_NEQ:
8621 case OPCM_32_BRR_ADDR_EQ_NEQ:
8622 case OPCM_32_BRR_GE:
8623 case OPCM_32_BRR_JLT:
8624 case OPCM_32_BRR_JNE:
8625 case OPCM_32_BRR_JNZ:
8626 case OPCM_32_BRR_LOOP:
8627 address = MASK_OP_BRR_DISP15_SEXT(ctx->opcode);
8628 r2 = MASK_OP_BRR_S2(ctx->opcode);
8629 r1 = MASK_OP_BRR_S1(ctx->opcode);
8630 gen_compute_branch(ctx, op1, r1, r2, 0, address);
8631 break;
8632 /* RC Format */
8633 case OPCM_32_RC_LOGICAL_SHIFT:
8634 decode_rc_logical_shift(ctx);
8635 break;
8636 case OPCM_32_RC_ACCUMULATOR:
8637 decode_rc_accumulator(ctx);
8638 break;
8639 case OPCM_32_RC_SERVICEROUTINE:
8640 decode_rc_serviceroutine(ctx);
8641 break;
8642 case OPCM_32_RC_MUL:
8643 decode_rc_mul(ctx);
8644 break;
8645 /* RCPW Format */
8646 case OPCM_32_RCPW_MASK_INSERT:
8647 decode_rcpw_insert(ctx);
8648 break;
8649 /* RCRR Format */
8650 case OPC1_32_RCRR_INSERT:
8651 r1 = MASK_OP_RCRR_S1(ctx->opcode);
8652 r2 = MASK_OP_RCRR_S3(ctx->opcode);
8653 r3 = MASK_OP_RCRR_D(ctx->opcode);
8654 const16 = MASK_OP_RCRR_CONST4(ctx->opcode);
8655 temp = tcg_const_i32(const16);
8656 temp2 = tcg_temp_new(); /* width*/
8657 temp3 = tcg_temp_new(); /* pos */
8659 CHECK_REG_PAIR(r3);
8661 tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
8662 tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
8664 gen_insert(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, temp2, temp3);
8666 tcg_temp_free(temp);
8667 tcg_temp_free(temp2);
8668 tcg_temp_free(temp3);
8669 break;
8670 /* RCRW Format */
8671 case OPCM_32_RCRW_MASK_INSERT:
8672 decode_rcrw_insert(ctx);
8673 break;
8674 /* RCR Format */
8675 case OPCM_32_RCR_COND_SELECT:
8676 decode_rcr_cond_select(ctx);
8677 break;
8678 case OPCM_32_RCR_MADD:
8679 decode_rcr_madd(ctx);
8680 break;
8681 case OPCM_32_RCR_MSUB:
8682 decode_rcr_msub(ctx);
8683 break;
8684 /* RLC Format */
8685 case OPC1_32_RLC_ADDI:
8686 case OPC1_32_RLC_ADDIH:
8687 case OPC1_32_RLC_ADDIH_A:
8688 case OPC1_32_RLC_MFCR:
8689 case OPC1_32_RLC_MOV:
8690 case OPC1_32_RLC_MOV_64:
8691 case OPC1_32_RLC_MOV_U:
8692 case OPC1_32_RLC_MOV_H:
8693 case OPC1_32_RLC_MOVH_A:
8694 case OPC1_32_RLC_MTCR:
8695 decode_rlc_opc(ctx, op1);
8696 break;
8697 /* RR Format */
8698 case OPCM_32_RR_ACCUMULATOR:
8699 decode_rr_accumulator(ctx);
8700 break;
8701 case OPCM_32_RR_LOGICAL_SHIFT:
8702 decode_rr_logical_shift(ctx);
8703 break;
8704 case OPCM_32_RR_ADDRESS:
8705 decode_rr_address(ctx);
8706 break;
8707 case OPCM_32_RR_IDIRECT:
8708 decode_rr_idirect(ctx);
8709 break;
8710 case OPCM_32_RR_DIVIDE:
8711 decode_rr_divide(ctx);
8712 break;
8713 /* RR1 Format */
8714 case OPCM_32_RR1_MUL:
8715 decode_rr1_mul(ctx);
8716 break;
8717 case OPCM_32_RR1_MULQ:
8718 decode_rr1_mulq(ctx);
8719 break;
8720 /* RR2 format */
8721 case OPCM_32_RR2_MUL:
8722 decode_rr2_mul(ctx);
8723 break;
8724 /* RRPW format */
8725 case OPCM_32_RRPW_EXTRACT_INSERT:
8726 decode_rrpw_extract_insert(ctx);
8727 break;
8728 case OPC1_32_RRPW_DEXTR:
8729 r1 = MASK_OP_RRPW_S1(ctx->opcode);
8730 r2 = MASK_OP_RRPW_S2(ctx->opcode);
8731 r3 = MASK_OP_RRPW_D(ctx->opcode);
8732 const16 = MASK_OP_RRPW_POS(ctx->opcode);
8733 if (r1 == r2) {
8734 tcg_gen_rotli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], const16);
8735 } else {
8736 temp = tcg_temp_new();
8737 tcg_gen_shli_tl(temp, cpu_gpr_d[r1], const16);
8738 tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], 32 - const16);
8739 tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
8740 tcg_temp_free(temp);
8742 break;
8743 /* RRR Format */
8744 case OPCM_32_RRR_COND_SELECT:
8745 decode_rrr_cond_select(ctx);
8746 break;
8747 case OPCM_32_RRR_DIVIDE:
8748 decode_rrr_divide(ctx);
8749 break;
8750 /* RRR2 Format */
8751 case OPCM_32_RRR2_MADD:
8752 decode_rrr2_madd(ctx);
8753 break;
8754 case OPCM_32_RRR2_MSUB:
8755 decode_rrr2_msub(ctx);
8756 break;
8757 /* RRR1 format */
8758 case OPCM_32_RRR1_MADD:
8759 decode_rrr1_madd(ctx);
8760 break;
8761 case OPCM_32_RRR1_MADDQ_H:
8762 decode_rrr1_maddq_h(ctx);
8763 break;
8764 case OPCM_32_RRR1_MADDSU_H:
8765 decode_rrr1_maddsu_h(ctx);
8766 break;
8767 case OPCM_32_RRR1_MSUB_H:
8768 decode_rrr1_msub(ctx);
8769 break;
8770 case OPCM_32_RRR1_MSUB_Q:
8771 decode_rrr1_msubq_h(ctx);
8772 break;
8773 case OPCM_32_RRR1_MSUBAD_H:
8774 decode_rrr1_msubad_h(ctx);
8775 break;
8776 /* RRRR format */
8777 case OPCM_32_RRRR_EXTRACT_INSERT:
8778 decode_rrrr_extract_insert(ctx);
8779 break;
8780 /* RRRW format */
8781 case OPCM_32_RRRW_EXTRACT_INSERT:
8782 decode_rrrw_extract_insert(ctx);
8783 break;
8784 /* SYS format */
8785 case OPCM_32_SYS_INTERRUPTS:
8786 decode_sys_interrupts(ctx);
8787 break;
8788 case OPC1_32_SYS_RSTV:
8789 tcg_gen_movi_tl(cpu_PSW_V, 0);
8790 tcg_gen_mov_tl(cpu_PSW_SV, cpu_PSW_V);
8791 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
8792 tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V);
8793 break;
8794 default:
8795 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8799 static bool tricore_insn_is_16bit(uint32_t insn)
8801 return (insn & 0x1) == 0;
8804 static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
8805 CPUState *cs)
8807 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8808 CPUTriCoreState *env = cs->env_ptr;
8809 ctx->mem_idx = cpu_mmu_index(env, false);
8810 ctx->hflags = (uint32_t)ctx->base.tb->flags;
8811 ctx->features = env->features;
8814 static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8818 static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8820 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8822 tcg_gen_insn_start(ctx->base.pc_next);
8825 static bool tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8826 const CPUBreakpoint *bp)
8828 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8829 generate_qemu_excp(ctx, EXCP_DEBUG);
8831 * The address covered by the breakpoint must be included in
8832 * [tb->pc, tb->pc + tb->size) in order to for it to be
8833 * properly cleared -- thus we increment the PC here so that
8834 * the logic setting tb->size below does the right thing.
8836 ctx->base.pc_next += 4;
8837 return true;
8840 static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx)
8843 * Return true if the insn at ctx->base.pc_next might cross a page boundary.
8844 * (False positives are OK, false negatives are not.)
8845 * Our caller ensures we are only called if dc->base.pc_next is less than
8846 * 4 bytes from the page boundary, so we cross the page if the first
8847 * 16 bits indicate that this is a 32 bit insn.
8849 uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next);
8851 return !tricore_insn_is_16bit(insn);
8855 static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8857 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8858 CPUTriCoreState *env = cpu->env_ptr;
8859 uint16_t insn_lo;
8860 bool is_16bit;
8862 insn_lo = cpu_lduw_code(env, ctx->base.pc_next);
8863 is_16bit = tricore_insn_is_16bit(insn_lo);
8864 if (is_16bit) {
8865 ctx->opcode = insn_lo;
8866 ctx->pc_succ_insn = ctx->base.pc_next + 2;
8867 decode_16Bit_opc(ctx);
8868 } else {
8869 uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2);
8870 ctx->opcode = insn_hi << 16 | insn_lo;
8871 ctx->pc_succ_insn = ctx->base.pc_next + 4;
8872 decode_32Bit_opc(ctx);
8874 ctx->base.pc_next = ctx->pc_succ_insn;
8876 if (ctx->base.is_jmp == DISAS_NEXT) {
8877 target_ulong page_start;
8879 page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
8880 if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE
8881 || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3
8882 && insn_crosses_page(env, ctx))) {
8883 ctx->base.is_jmp = DISAS_TOO_MANY;
8888 static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8890 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8892 switch (ctx->base.is_jmp) {
8893 case DISAS_TOO_MANY:
8894 gen_goto_tb(ctx, 0, ctx->base.pc_next);
8895 break;
8896 case DISAS_NORETURN:
8897 break;
8898 default:
8899 g_assert_not_reached();
8903 static void tricore_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
8905 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
8906 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
8909 static const TranslatorOps tricore_tr_ops = {
8910 .init_disas_context = tricore_tr_init_disas_context,
8911 .tb_start = tricore_tr_tb_start,
8912 .insn_start = tricore_tr_insn_start,
8913 .breakpoint_check = tricore_tr_breakpoint_check,
8914 .translate_insn = tricore_tr_translate_insn,
8915 .tb_stop = tricore_tr_tb_stop,
8916 .disas_log = tricore_tr_disas_log,
8920 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
8922 DisasContext ctx;
8923 translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns);
8926 void
8927 restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb,
8928 target_ulong *data)
8930 env->PC = data[0];
8934 * Initialization
8938 void cpu_state_reset(CPUTriCoreState *env)
8940 /* Reset Regs to Default Value */
8941 env->PSW = 0xb80;
8942 fpu_set_state(env);
8945 static void tricore_tcg_init_csfr(void)
8947 cpu_PCXI = tcg_global_mem_new(cpu_env,
8948 offsetof(CPUTriCoreState, PCXI), "PCXI");
8949 cpu_PSW = tcg_global_mem_new(cpu_env,
8950 offsetof(CPUTriCoreState, PSW), "PSW");
8951 cpu_PC = tcg_global_mem_new(cpu_env,
8952 offsetof(CPUTriCoreState, PC), "PC");
8953 cpu_ICR = tcg_global_mem_new(cpu_env,
8954 offsetof(CPUTriCoreState, ICR), "ICR");
8957 void tricore_tcg_init(void)
8959 int i;
8961 /* reg init */
8962 for (i = 0 ; i < 16 ; i++) {
8963 cpu_gpr_a[i] = tcg_global_mem_new(cpu_env,
8964 offsetof(CPUTriCoreState, gpr_a[i]),
8965 regnames_a[i]);
8967 for (i = 0 ; i < 16 ; i++) {
8968 cpu_gpr_d[i] = tcg_global_mem_new(cpu_env,
8969 offsetof(CPUTriCoreState, gpr_d[i]),
8970 regnames_d[i]);
8972 tricore_tcg_init_csfr();
8973 /* init PSW flag cache */
8974 cpu_PSW_C = tcg_global_mem_new(cpu_env,
8975 offsetof(CPUTriCoreState, PSW_USB_C),
8976 "PSW_C");
8977 cpu_PSW_V = tcg_global_mem_new(cpu_env,
8978 offsetof(CPUTriCoreState, PSW_USB_V),
8979 "PSW_V");
8980 cpu_PSW_SV = tcg_global_mem_new(cpu_env,
8981 offsetof(CPUTriCoreState, PSW_USB_SV),
8982 "PSW_SV");
8983 cpu_PSW_AV = tcg_global_mem_new(cpu_env,
8984 offsetof(CPUTriCoreState, PSW_USB_AV),
8985 "PSW_AV");
8986 cpu_PSW_SAV = tcg_global_mem_new(cpu_env,
8987 offsetof(CPUTriCoreState, PSW_USB_SAV),
8988 "PSW_SAV");