qom: Use returned bool to check for failure, Coccinelle part
[qemu/ar7.git] / target / tricore / translate.c
blob7752630ac14c6ce151dc4f6ecf42ffa868c3f7e5
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 > 31 undefined result */
5781 if (pos + width <= 31) {
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;
6993 op2 = MASK_OP_RRPW_OP2(ctx->opcode);
6994 r1 = MASK_OP_RRPW_S1(ctx->opcode);
6995 r2 = MASK_OP_RRPW_S2(ctx->opcode);
6996 r3 = MASK_OP_RRPW_D(ctx->opcode);
6997 pos = MASK_OP_RRPW_POS(ctx->opcode);
6998 width = MASK_OP_RRPW_WIDTH(ctx->opcode);
7000 switch (op2) {
7001 case OPC2_32_RRPW_EXTR:
7002 if (pos + width <= 31) {
7003 /* optimize special cases */
7004 if ((pos == 0) && (width == 8)) {
7005 tcg_gen_ext8s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
7006 } else if ((pos == 0) && (width == 16)) {
7007 tcg_gen_ext16s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
7008 } else {
7009 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 32 - pos - width);
7010 tcg_gen_sari_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 32 - width);
7013 break;
7014 case OPC2_32_RRPW_EXTR_U:
7015 if (width == 0) {
7016 tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
7017 } else {
7018 tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos);
7019 tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], ~0u >> (32-width));
7021 break;
7022 case OPC2_32_RRPW_IMASK:
7023 CHECK_REG_PAIR(r3);
7024 if (pos + width <= 31) {
7025 tcg_gen_movi_tl(cpu_gpr_d[r3+1], ((1u << width) - 1) << pos);
7026 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], pos);
7028 break;
7029 case OPC2_32_RRPW_INSERT:
7030 if (pos + width <= 32) {
7031 tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
7032 pos, width);
7034 break;
7035 default:
7036 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7040 /* RRR format */
7041 static void decode_rrr_cond_select(DisasContext *ctx)
7043 uint32_t op2;
7044 int r1, r2, r3, r4;
7045 TCGv temp;
7047 op2 = MASK_OP_RRR_OP2(ctx->opcode);
7048 r1 = MASK_OP_RRR_S1(ctx->opcode);
7049 r2 = MASK_OP_RRR_S2(ctx->opcode);
7050 r3 = MASK_OP_RRR_S3(ctx->opcode);
7051 r4 = MASK_OP_RRR_D(ctx->opcode);
7053 switch (op2) {
7054 case OPC2_32_RRR_CADD:
7055 gen_cond_add(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
7056 cpu_gpr_d[r4], cpu_gpr_d[r3]);
7057 break;
7058 case OPC2_32_RRR_CADDN:
7059 gen_cond_add(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7060 cpu_gpr_d[r3]);
7061 break;
7062 case OPC2_32_RRR_CSUB:
7063 gen_cond_sub(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7064 cpu_gpr_d[r3]);
7065 break;
7066 case OPC2_32_RRR_CSUBN:
7067 gen_cond_sub(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
7068 cpu_gpr_d[r3]);
7069 break;
7070 case OPC2_32_RRR_SEL:
7071 temp = tcg_const_i32(0);
7072 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
7073 cpu_gpr_d[r1], cpu_gpr_d[r2]);
7074 tcg_temp_free(temp);
7075 break;
7076 case OPC2_32_RRR_SELN:
7077 temp = tcg_const_i32(0);
7078 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
7079 cpu_gpr_d[r1], cpu_gpr_d[r2]);
7080 tcg_temp_free(temp);
7081 break;
7082 default:
7083 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7087 static void decode_rrr_divide(DisasContext *ctx)
7089 uint32_t op2;
7091 int r1, r2, r3, r4;
7093 op2 = MASK_OP_RRR_OP2(ctx->opcode);
7094 r1 = MASK_OP_RRR_S1(ctx->opcode);
7095 r2 = MASK_OP_RRR_S2(ctx->opcode);
7096 r3 = MASK_OP_RRR_S3(ctx->opcode);
7097 r4 = MASK_OP_RRR_D(ctx->opcode);
7099 switch (op2) {
7100 case OPC2_32_RRR_DVADJ:
7101 CHECK_REG_PAIR(r3);
7102 CHECK_REG_PAIR(r4);
7103 GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7104 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7105 break;
7106 case OPC2_32_RRR_DVSTEP:
7107 CHECK_REG_PAIR(r3);
7108 CHECK_REG_PAIR(r4);
7109 GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7110 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7111 break;
7112 case OPC2_32_RRR_DVSTEP_U:
7113 CHECK_REG_PAIR(r3);
7114 CHECK_REG_PAIR(r4);
7115 GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7116 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7117 break;
7118 case OPC2_32_RRR_IXMAX:
7119 CHECK_REG_PAIR(r3);
7120 CHECK_REG_PAIR(r4);
7121 GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7122 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7123 break;
7124 case OPC2_32_RRR_IXMAX_U:
7125 CHECK_REG_PAIR(r3);
7126 CHECK_REG_PAIR(r4);
7127 GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7128 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7129 break;
7130 case OPC2_32_RRR_IXMIN:
7131 CHECK_REG_PAIR(r3);
7132 CHECK_REG_PAIR(r4);
7133 GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7134 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7135 break;
7136 case OPC2_32_RRR_IXMIN_U:
7137 CHECK_REG_PAIR(r3);
7138 CHECK_REG_PAIR(r4);
7139 GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7140 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7141 break;
7142 case OPC2_32_RRR_PACK:
7143 CHECK_REG_PAIR(r3);
7144 gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
7145 cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
7146 break;
7147 case OPC2_32_RRR_ADD_F:
7148 gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
7149 break;
7150 case OPC2_32_RRR_SUB_F:
7151 gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
7152 break;
7153 case OPC2_32_RRR_MADD_F:
7154 gen_helper_fmadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7155 cpu_gpr_d[r2], cpu_gpr_d[r3]);
7156 break;
7157 case OPC2_32_RRR_MSUB_F:
7158 gen_helper_fmsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7159 cpu_gpr_d[r2], cpu_gpr_d[r3]);
7160 break;
7161 default:
7162 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7166 /* RRR2 format */
7167 static void decode_rrr2_madd(DisasContext *ctx)
7169 uint32_t op2;
7170 uint32_t r1, r2, r3, r4;
7172 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
7173 r1 = MASK_OP_RRR2_S1(ctx->opcode);
7174 r2 = MASK_OP_RRR2_S2(ctx->opcode);
7175 r3 = MASK_OP_RRR2_S3(ctx->opcode);
7176 r4 = MASK_OP_RRR2_D(ctx->opcode);
7177 switch (op2) {
7178 case OPC2_32_RRR2_MADD_32:
7179 gen_madd32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
7180 cpu_gpr_d[r2]);
7181 break;
7182 case OPC2_32_RRR2_MADD_64:
7183 CHECK_REG_PAIR(r4);
7184 CHECK_REG_PAIR(r3);
7185 gen_madd64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7186 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7187 break;
7188 case OPC2_32_RRR2_MADDS_32:
7189 gen_helper_madd32_ssov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7190 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7191 break;
7192 case OPC2_32_RRR2_MADDS_64:
7193 CHECK_REG_PAIR(r4);
7194 CHECK_REG_PAIR(r3);
7195 gen_madds_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7196 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7197 break;
7198 case OPC2_32_RRR2_MADD_U_64:
7199 CHECK_REG_PAIR(r4);
7200 CHECK_REG_PAIR(r3);
7201 gen_maddu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7202 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7203 break;
7204 case OPC2_32_RRR2_MADDS_U_32:
7205 gen_helper_madd32_suov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7206 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7207 break;
7208 case OPC2_32_RRR2_MADDS_U_64:
7209 CHECK_REG_PAIR(r4);
7210 CHECK_REG_PAIR(r3);
7211 gen_maddsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7212 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7213 break;
7214 default:
7215 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7219 static void decode_rrr2_msub(DisasContext *ctx)
7221 uint32_t op2;
7222 uint32_t r1, r2, r3, r4;
7224 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
7225 r1 = MASK_OP_RRR2_S1(ctx->opcode);
7226 r2 = MASK_OP_RRR2_S2(ctx->opcode);
7227 r3 = MASK_OP_RRR2_S3(ctx->opcode);
7228 r4 = MASK_OP_RRR2_D(ctx->opcode);
7230 switch (op2) {
7231 case OPC2_32_RRR2_MSUB_32:
7232 gen_msub32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
7233 cpu_gpr_d[r2]);
7234 break;
7235 case OPC2_32_RRR2_MSUB_64:
7236 CHECK_REG_PAIR(r4);
7237 CHECK_REG_PAIR(r3);
7238 gen_msub64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7239 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7240 break;
7241 case OPC2_32_RRR2_MSUBS_32:
7242 gen_helper_msub32_ssov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7243 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7244 break;
7245 case OPC2_32_RRR2_MSUBS_64:
7246 CHECK_REG_PAIR(r4);
7247 CHECK_REG_PAIR(r3);
7248 gen_msubs_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7249 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7250 break;
7251 case OPC2_32_RRR2_MSUB_U_64:
7252 gen_msubu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7253 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7254 break;
7255 case OPC2_32_RRR2_MSUBS_U_32:
7256 gen_helper_msub32_suov(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1],
7257 cpu_gpr_d[r3], cpu_gpr_d[r2]);
7258 break;
7259 case OPC2_32_RRR2_MSUBS_U_64:
7260 CHECK_REG_PAIR(r4);
7261 CHECK_REG_PAIR(r3);
7262 gen_msubsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
7263 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
7264 break;
7265 default:
7266 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7270 /* RRR1 format */
7271 static void decode_rrr1_madd(DisasContext *ctx)
7273 uint32_t op2;
7274 uint32_t r1, r2, r3, r4, n;
7276 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7277 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7278 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7279 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7280 r4 = MASK_OP_RRR1_D(ctx->opcode);
7281 n = MASK_OP_RRR1_N(ctx->opcode);
7283 switch (op2) {
7284 case OPC2_32_RRR1_MADD_H_LL:
7285 CHECK_REG_PAIR(r4);
7286 CHECK_REG_PAIR(r3);
7287 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7288 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7289 break;
7290 case OPC2_32_RRR1_MADD_H_LU:
7291 CHECK_REG_PAIR(r4);
7292 CHECK_REG_PAIR(r3);
7293 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7294 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7295 break;
7296 case OPC2_32_RRR1_MADD_H_UL:
7297 CHECK_REG_PAIR(r4);
7298 CHECK_REG_PAIR(r3);
7299 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7300 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7301 break;
7302 case OPC2_32_RRR1_MADD_H_UU:
7303 CHECK_REG_PAIR(r4);
7304 CHECK_REG_PAIR(r3);
7305 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7306 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7307 break;
7308 case OPC2_32_RRR1_MADDS_H_LL:
7309 CHECK_REG_PAIR(r4);
7310 CHECK_REG_PAIR(r3);
7311 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7312 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7313 break;
7314 case OPC2_32_RRR1_MADDS_H_LU:
7315 CHECK_REG_PAIR(r4);
7316 CHECK_REG_PAIR(r3);
7317 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7318 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7319 break;
7320 case OPC2_32_RRR1_MADDS_H_UL:
7321 CHECK_REG_PAIR(r4);
7322 CHECK_REG_PAIR(r3);
7323 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7324 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7325 break;
7326 case OPC2_32_RRR1_MADDS_H_UU:
7327 CHECK_REG_PAIR(r4);
7328 CHECK_REG_PAIR(r3);
7329 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7330 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7331 break;
7332 case OPC2_32_RRR1_MADDM_H_LL:
7333 CHECK_REG_PAIR(r4);
7334 CHECK_REG_PAIR(r3);
7335 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7336 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7337 break;
7338 case OPC2_32_RRR1_MADDM_H_LU:
7339 CHECK_REG_PAIR(r4);
7340 CHECK_REG_PAIR(r3);
7341 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7342 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7343 break;
7344 case OPC2_32_RRR1_MADDM_H_UL:
7345 CHECK_REG_PAIR(r4);
7346 CHECK_REG_PAIR(r3);
7347 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7348 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7349 break;
7350 case OPC2_32_RRR1_MADDM_H_UU:
7351 CHECK_REG_PAIR(r4);
7352 CHECK_REG_PAIR(r3);
7353 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7354 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7355 break;
7356 case OPC2_32_RRR1_MADDMS_H_LL:
7357 CHECK_REG_PAIR(r4);
7358 CHECK_REG_PAIR(r3);
7359 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7360 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7361 break;
7362 case OPC2_32_RRR1_MADDMS_H_LU:
7363 CHECK_REG_PAIR(r4);
7364 CHECK_REG_PAIR(r3);
7365 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7366 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7367 break;
7368 case OPC2_32_RRR1_MADDMS_H_UL:
7369 CHECK_REG_PAIR(r4);
7370 CHECK_REG_PAIR(r3);
7371 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7372 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7373 break;
7374 case OPC2_32_RRR1_MADDMS_H_UU:
7375 CHECK_REG_PAIR(r4);
7376 CHECK_REG_PAIR(r3);
7377 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7378 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7379 break;
7380 case OPC2_32_RRR1_MADDR_H_LL:
7381 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7382 cpu_gpr_d[r2], n, MODE_LL);
7383 break;
7384 case OPC2_32_RRR1_MADDR_H_LU:
7385 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7386 cpu_gpr_d[r2], n, MODE_LU);
7387 break;
7388 case OPC2_32_RRR1_MADDR_H_UL:
7389 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7390 cpu_gpr_d[r2], n, MODE_UL);
7391 break;
7392 case OPC2_32_RRR1_MADDR_H_UU:
7393 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7394 cpu_gpr_d[r2], n, MODE_UU);
7395 break;
7396 case OPC2_32_RRR1_MADDRS_H_LL:
7397 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7398 cpu_gpr_d[r2], n, MODE_LL);
7399 break;
7400 case OPC2_32_RRR1_MADDRS_H_LU:
7401 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7402 cpu_gpr_d[r2], n, MODE_LU);
7403 break;
7404 case OPC2_32_RRR1_MADDRS_H_UL:
7405 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7406 cpu_gpr_d[r2], n, MODE_UL);
7407 break;
7408 case OPC2_32_RRR1_MADDRS_H_UU:
7409 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7410 cpu_gpr_d[r2], n, MODE_UU);
7411 break;
7412 default:
7413 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7417 static void decode_rrr1_maddq_h(DisasContext *ctx)
7419 uint32_t op2;
7420 uint32_t r1, r2, r3, r4, n;
7421 TCGv temp, temp2;
7423 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7424 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7425 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7426 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7427 r4 = MASK_OP_RRR1_D(ctx->opcode);
7428 n = MASK_OP_RRR1_N(ctx->opcode);
7430 temp = tcg_const_i32(n);
7431 temp2 = tcg_temp_new();
7433 switch (op2) {
7434 case OPC2_32_RRR1_MADD_Q_32:
7435 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7436 cpu_gpr_d[r2], n, 32);
7437 break;
7438 case OPC2_32_RRR1_MADD_Q_64:
7439 CHECK_REG_PAIR(r4);
7440 CHECK_REG_PAIR(r3);
7441 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7442 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7444 break;
7445 case OPC2_32_RRR1_MADD_Q_32_L:
7446 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7447 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7448 temp, n, 16);
7449 break;
7450 case OPC2_32_RRR1_MADD_Q_64_L:
7451 CHECK_REG_PAIR(r4);
7452 CHECK_REG_PAIR(r3);
7453 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7454 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7455 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7457 break;
7458 case OPC2_32_RRR1_MADD_Q_32_U:
7459 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7460 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7461 temp, n, 16);
7462 break;
7463 case OPC2_32_RRR1_MADD_Q_64_U:
7464 CHECK_REG_PAIR(r4);
7465 CHECK_REG_PAIR(r3);
7466 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7467 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7468 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7470 break;
7471 case OPC2_32_RRR1_MADD_Q_32_LL:
7472 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7473 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7474 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7475 break;
7476 case OPC2_32_RRR1_MADD_Q_64_LL:
7477 CHECK_REG_PAIR(r4);
7478 CHECK_REG_PAIR(r3);
7479 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7480 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7481 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7482 cpu_gpr_d[r3+1], temp, temp2, n);
7483 break;
7484 case OPC2_32_RRR1_MADD_Q_32_UU:
7485 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7486 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7487 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7488 break;
7489 case OPC2_32_RRR1_MADD_Q_64_UU:
7490 CHECK_REG_PAIR(r4);
7491 CHECK_REG_PAIR(r3);
7492 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7493 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7494 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7495 cpu_gpr_d[r3+1], temp, temp2, n);
7496 break;
7497 case OPC2_32_RRR1_MADDS_Q_32:
7498 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7499 cpu_gpr_d[r2], n, 32);
7500 break;
7501 case OPC2_32_RRR1_MADDS_Q_64:
7502 CHECK_REG_PAIR(r4);
7503 CHECK_REG_PAIR(r3);
7504 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7505 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7507 break;
7508 case OPC2_32_RRR1_MADDS_Q_32_L:
7509 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7510 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7511 temp, n, 16);
7512 break;
7513 case OPC2_32_RRR1_MADDS_Q_64_L:
7514 CHECK_REG_PAIR(r4);
7515 CHECK_REG_PAIR(r3);
7516 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7517 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7518 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7520 break;
7521 case OPC2_32_RRR1_MADDS_Q_32_U:
7522 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7523 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7524 temp, n, 16);
7525 break;
7526 case OPC2_32_RRR1_MADDS_Q_64_U:
7527 CHECK_REG_PAIR(r4);
7528 CHECK_REG_PAIR(r3);
7529 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7530 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7531 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7533 break;
7534 case OPC2_32_RRR1_MADDS_Q_32_LL:
7535 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7536 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7537 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7538 break;
7539 case OPC2_32_RRR1_MADDS_Q_64_LL:
7540 CHECK_REG_PAIR(r4);
7541 CHECK_REG_PAIR(r3);
7542 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7543 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7544 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7545 cpu_gpr_d[r3+1], temp, temp2, n);
7546 break;
7547 case OPC2_32_RRR1_MADDS_Q_32_UU:
7548 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7549 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7550 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7551 break;
7552 case OPC2_32_RRR1_MADDS_Q_64_UU:
7553 CHECK_REG_PAIR(r4);
7554 CHECK_REG_PAIR(r3);
7555 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7556 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7557 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7558 cpu_gpr_d[r3+1], temp, temp2, n);
7559 break;
7560 case OPC2_32_RRR1_MADDR_H_64_UL:
7561 CHECK_REG_PAIR(r3);
7562 gen_maddr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7563 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7564 break;
7565 case OPC2_32_RRR1_MADDRS_H_64_UL:
7566 CHECK_REG_PAIR(r3);
7567 gen_maddr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7568 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7569 break;
7570 case OPC2_32_RRR1_MADDR_Q_32_LL:
7571 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7572 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7573 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7574 break;
7575 case OPC2_32_RRR1_MADDR_Q_32_UU:
7576 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7577 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7578 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7579 break;
7580 case OPC2_32_RRR1_MADDRS_Q_32_LL:
7581 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7582 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7583 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7584 break;
7585 case OPC2_32_RRR1_MADDRS_Q_32_UU:
7586 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7587 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7588 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7589 break;
7590 default:
7591 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7593 tcg_temp_free(temp);
7594 tcg_temp_free(temp2);
7597 static void decode_rrr1_maddsu_h(DisasContext *ctx)
7599 uint32_t op2;
7600 uint32_t r1, r2, r3, r4, n;
7602 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7603 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7604 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7605 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7606 r4 = MASK_OP_RRR1_D(ctx->opcode);
7607 n = MASK_OP_RRR1_N(ctx->opcode);
7609 switch (op2) {
7610 case OPC2_32_RRR1_MADDSU_H_32_LL:
7611 CHECK_REG_PAIR(r4);
7612 CHECK_REG_PAIR(r3);
7613 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7614 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7615 break;
7616 case OPC2_32_RRR1_MADDSU_H_32_LU:
7617 CHECK_REG_PAIR(r4);
7618 CHECK_REG_PAIR(r3);
7619 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7620 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7621 break;
7622 case OPC2_32_RRR1_MADDSU_H_32_UL:
7623 CHECK_REG_PAIR(r4);
7624 CHECK_REG_PAIR(r3);
7625 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7626 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7627 break;
7628 case OPC2_32_RRR1_MADDSU_H_32_UU:
7629 CHECK_REG_PAIR(r4);
7630 CHECK_REG_PAIR(r3);
7631 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7632 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7633 break;
7634 case OPC2_32_RRR1_MADDSUS_H_32_LL:
7635 CHECK_REG_PAIR(r4);
7636 CHECK_REG_PAIR(r3);
7637 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7638 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7639 n, MODE_LL);
7640 break;
7641 case OPC2_32_RRR1_MADDSUS_H_32_LU:
7642 CHECK_REG_PAIR(r4);
7643 CHECK_REG_PAIR(r3);
7644 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7645 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7646 n, MODE_LU);
7647 break;
7648 case OPC2_32_RRR1_MADDSUS_H_32_UL:
7649 CHECK_REG_PAIR(r4);
7650 CHECK_REG_PAIR(r3);
7651 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7652 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7653 n, MODE_UL);
7654 break;
7655 case OPC2_32_RRR1_MADDSUS_H_32_UU:
7656 CHECK_REG_PAIR(r4);
7657 CHECK_REG_PAIR(r3);
7658 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7659 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7660 n, MODE_UU);
7661 break;
7662 case OPC2_32_RRR1_MADDSUM_H_64_LL:
7663 CHECK_REG_PAIR(r4);
7664 CHECK_REG_PAIR(r3);
7665 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7666 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7667 n, MODE_LL);
7668 break;
7669 case OPC2_32_RRR1_MADDSUM_H_64_LU:
7670 CHECK_REG_PAIR(r4);
7671 CHECK_REG_PAIR(r3);
7672 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7673 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7674 n, MODE_LU);
7675 break;
7676 case OPC2_32_RRR1_MADDSUM_H_64_UL:
7677 CHECK_REG_PAIR(r4);
7678 CHECK_REG_PAIR(r3);
7679 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7680 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7681 n, MODE_UL);
7682 break;
7683 case OPC2_32_RRR1_MADDSUM_H_64_UU:
7684 CHECK_REG_PAIR(r4);
7685 CHECK_REG_PAIR(r3);
7686 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7687 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7688 n, MODE_UU);
7689 break;
7690 case OPC2_32_RRR1_MADDSUMS_H_64_LL:
7691 CHECK_REG_PAIR(r4);
7692 CHECK_REG_PAIR(r3);
7693 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7694 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7695 n, MODE_LL);
7696 break;
7697 case OPC2_32_RRR1_MADDSUMS_H_64_LU:
7698 CHECK_REG_PAIR(r4);
7699 CHECK_REG_PAIR(r3);
7700 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7701 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7702 n, MODE_LU);
7703 break;
7704 case OPC2_32_RRR1_MADDSUMS_H_64_UL:
7705 CHECK_REG_PAIR(r4);
7706 CHECK_REG_PAIR(r3);
7707 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7708 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7709 n, MODE_UL);
7710 break;
7711 case OPC2_32_RRR1_MADDSUMS_H_64_UU:
7712 CHECK_REG_PAIR(r4);
7713 CHECK_REG_PAIR(r3);
7714 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7715 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7716 n, MODE_UU);
7717 break;
7718 case OPC2_32_RRR1_MADDSUR_H_16_LL:
7719 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7720 cpu_gpr_d[r2], n, MODE_LL);
7721 break;
7722 case OPC2_32_RRR1_MADDSUR_H_16_LU:
7723 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7724 cpu_gpr_d[r2], n, MODE_LU);
7725 break;
7726 case OPC2_32_RRR1_MADDSUR_H_16_UL:
7727 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7728 cpu_gpr_d[r2], n, MODE_UL);
7729 break;
7730 case OPC2_32_RRR1_MADDSUR_H_16_UU:
7731 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7732 cpu_gpr_d[r2], n, MODE_UU);
7733 break;
7734 case OPC2_32_RRR1_MADDSURS_H_16_LL:
7735 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7736 cpu_gpr_d[r2], n, MODE_LL);
7737 break;
7738 case OPC2_32_RRR1_MADDSURS_H_16_LU:
7739 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7740 cpu_gpr_d[r2], n, MODE_LU);
7741 break;
7742 case OPC2_32_RRR1_MADDSURS_H_16_UL:
7743 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7744 cpu_gpr_d[r2], n, MODE_UL);
7745 break;
7746 case OPC2_32_RRR1_MADDSURS_H_16_UU:
7747 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7748 cpu_gpr_d[r2], n, MODE_UU);
7749 break;
7750 default:
7751 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7755 static void decode_rrr1_msub(DisasContext *ctx)
7757 uint32_t op2;
7758 uint32_t r1, r2, r3, r4, n;
7760 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7761 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7762 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7763 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7764 r4 = MASK_OP_RRR1_D(ctx->opcode);
7765 n = MASK_OP_RRR1_N(ctx->opcode);
7767 switch (op2) {
7768 case OPC2_32_RRR1_MSUB_H_LL:
7769 CHECK_REG_PAIR(r4);
7770 CHECK_REG_PAIR(r3);
7771 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7772 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7773 break;
7774 case OPC2_32_RRR1_MSUB_H_LU:
7775 CHECK_REG_PAIR(r4);
7776 CHECK_REG_PAIR(r3);
7777 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7778 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7779 break;
7780 case OPC2_32_RRR1_MSUB_H_UL:
7781 CHECK_REG_PAIR(r4);
7782 CHECK_REG_PAIR(r3);
7783 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7784 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7785 break;
7786 case OPC2_32_RRR1_MSUB_H_UU:
7787 CHECK_REG_PAIR(r4);
7788 CHECK_REG_PAIR(r3);
7789 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7790 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7791 break;
7792 case OPC2_32_RRR1_MSUBS_H_LL:
7793 CHECK_REG_PAIR(r4);
7794 CHECK_REG_PAIR(r3);
7795 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7796 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7797 break;
7798 case OPC2_32_RRR1_MSUBS_H_LU:
7799 CHECK_REG_PAIR(r4);
7800 CHECK_REG_PAIR(r3);
7801 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7802 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7803 break;
7804 case OPC2_32_RRR1_MSUBS_H_UL:
7805 CHECK_REG_PAIR(r4);
7806 CHECK_REG_PAIR(r3);
7807 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7808 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7809 break;
7810 case OPC2_32_RRR1_MSUBS_H_UU:
7811 CHECK_REG_PAIR(r4);
7812 CHECK_REG_PAIR(r3);
7813 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7814 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7815 break;
7816 case OPC2_32_RRR1_MSUBM_H_LL:
7817 CHECK_REG_PAIR(r4);
7818 CHECK_REG_PAIR(r3);
7819 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7820 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7821 break;
7822 case OPC2_32_RRR1_MSUBM_H_LU:
7823 CHECK_REG_PAIR(r4);
7824 CHECK_REG_PAIR(r3);
7825 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7826 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7827 break;
7828 case OPC2_32_RRR1_MSUBM_H_UL:
7829 CHECK_REG_PAIR(r4);
7830 CHECK_REG_PAIR(r3);
7831 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7832 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7833 break;
7834 case OPC2_32_RRR1_MSUBM_H_UU:
7835 CHECK_REG_PAIR(r4);
7836 CHECK_REG_PAIR(r3);
7837 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7838 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7839 break;
7840 case OPC2_32_RRR1_MSUBMS_H_LL:
7841 CHECK_REG_PAIR(r4);
7842 CHECK_REG_PAIR(r3);
7843 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7844 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7845 break;
7846 case OPC2_32_RRR1_MSUBMS_H_LU:
7847 CHECK_REG_PAIR(r4);
7848 CHECK_REG_PAIR(r3);
7849 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7850 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7851 break;
7852 case OPC2_32_RRR1_MSUBMS_H_UL:
7853 CHECK_REG_PAIR(r4);
7854 CHECK_REG_PAIR(r3);
7855 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7856 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7857 break;
7858 case OPC2_32_RRR1_MSUBMS_H_UU:
7859 CHECK_REG_PAIR(r4);
7860 CHECK_REG_PAIR(r3);
7861 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7862 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7863 break;
7864 case OPC2_32_RRR1_MSUBR_H_LL:
7865 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7866 cpu_gpr_d[r2], n, MODE_LL);
7867 break;
7868 case OPC2_32_RRR1_MSUBR_H_LU:
7869 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7870 cpu_gpr_d[r2], n, MODE_LU);
7871 break;
7872 case OPC2_32_RRR1_MSUBR_H_UL:
7873 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7874 cpu_gpr_d[r2], n, MODE_UL);
7875 break;
7876 case OPC2_32_RRR1_MSUBR_H_UU:
7877 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7878 cpu_gpr_d[r2], n, MODE_UU);
7879 break;
7880 case OPC2_32_RRR1_MSUBRS_H_LL:
7881 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7882 cpu_gpr_d[r2], n, MODE_LL);
7883 break;
7884 case OPC2_32_RRR1_MSUBRS_H_LU:
7885 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7886 cpu_gpr_d[r2], n, MODE_LU);
7887 break;
7888 case OPC2_32_RRR1_MSUBRS_H_UL:
7889 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7890 cpu_gpr_d[r2], n, MODE_UL);
7891 break;
7892 case OPC2_32_RRR1_MSUBRS_H_UU:
7893 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7894 cpu_gpr_d[r2], n, MODE_UU);
7895 break;
7896 default:
7897 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7901 static void decode_rrr1_msubq_h(DisasContext *ctx)
7903 uint32_t op2;
7904 uint32_t r1, r2, r3, r4, n;
7905 TCGv temp, temp2;
7907 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7908 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7909 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7910 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7911 r4 = MASK_OP_RRR1_D(ctx->opcode);
7912 n = MASK_OP_RRR1_N(ctx->opcode);
7914 temp = tcg_const_i32(n);
7915 temp2 = tcg_temp_new();
7917 switch (op2) {
7918 case OPC2_32_RRR1_MSUB_Q_32:
7919 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7920 cpu_gpr_d[r2], n, 32);
7921 break;
7922 case OPC2_32_RRR1_MSUB_Q_64:
7923 CHECK_REG_PAIR(r4);
7924 CHECK_REG_PAIR(r3);
7925 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7926 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7928 break;
7929 case OPC2_32_RRR1_MSUB_Q_32_L:
7930 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7931 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7932 temp, n, 16);
7933 break;
7934 case OPC2_32_RRR1_MSUB_Q_64_L:
7935 CHECK_REG_PAIR(r4);
7936 CHECK_REG_PAIR(r3);
7937 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7938 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7939 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7941 break;
7942 case OPC2_32_RRR1_MSUB_Q_32_U:
7943 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7944 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7945 temp, n, 16);
7946 break;
7947 case OPC2_32_RRR1_MSUB_Q_64_U:
7948 CHECK_REG_PAIR(r4);
7949 CHECK_REG_PAIR(r3);
7950 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7951 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7952 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7954 break;
7955 case OPC2_32_RRR1_MSUB_Q_32_LL:
7956 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7957 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7958 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7959 break;
7960 case OPC2_32_RRR1_MSUB_Q_64_LL:
7961 CHECK_REG_PAIR(r4);
7962 CHECK_REG_PAIR(r3);
7963 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7964 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7965 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7966 cpu_gpr_d[r3+1], temp, temp2, n);
7967 break;
7968 case OPC2_32_RRR1_MSUB_Q_32_UU:
7969 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7970 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7971 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7972 break;
7973 case OPC2_32_RRR1_MSUB_Q_64_UU:
7974 CHECK_REG_PAIR(r4);
7975 CHECK_REG_PAIR(r3);
7976 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7977 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7978 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7979 cpu_gpr_d[r3+1], temp, temp2, n);
7980 break;
7981 case OPC2_32_RRR1_MSUBS_Q_32:
7982 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7983 cpu_gpr_d[r2], n, 32);
7984 break;
7985 case OPC2_32_RRR1_MSUBS_Q_64:
7986 CHECK_REG_PAIR(r4);
7987 CHECK_REG_PAIR(r3);
7988 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7989 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7991 break;
7992 case OPC2_32_RRR1_MSUBS_Q_32_L:
7993 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7994 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7995 temp, n, 16);
7996 break;
7997 case OPC2_32_RRR1_MSUBS_Q_64_L:
7998 CHECK_REG_PAIR(r4);
7999 CHECK_REG_PAIR(r3);
8000 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
8001 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8002 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
8004 break;
8005 case OPC2_32_RRR1_MSUBS_Q_32_U:
8006 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
8007 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8008 temp, n, 16);
8009 break;
8010 case OPC2_32_RRR1_MSUBS_Q_64_U:
8011 CHECK_REG_PAIR(r4);
8012 CHECK_REG_PAIR(r3);
8013 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
8014 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8015 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
8017 break;
8018 case OPC2_32_RRR1_MSUBS_Q_32_LL:
8019 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8020 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8021 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8022 break;
8023 case OPC2_32_RRR1_MSUBS_Q_64_LL:
8024 CHECK_REG_PAIR(r4);
8025 CHECK_REG_PAIR(r3);
8026 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8027 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8028 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8029 cpu_gpr_d[r3+1], temp, temp2, n);
8030 break;
8031 case OPC2_32_RRR1_MSUBS_Q_32_UU:
8032 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8033 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8034 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8035 break;
8036 case OPC2_32_RRR1_MSUBS_Q_64_UU:
8037 CHECK_REG_PAIR(r4);
8038 CHECK_REG_PAIR(r3);
8039 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8040 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8041 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8042 cpu_gpr_d[r3+1], temp, temp2, n);
8043 break;
8044 case OPC2_32_RRR1_MSUBR_H_64_UL:
8045 CHECK_REG_PAIR(r3);
8046 gen_msubr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
8047 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
8048 break;
8049 case OPC2_32_RRR1_MSUBRS_H_64_UL:
8050 CHECK_REG_PAIR(r3);
8051 gen_msubr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
8052 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
8053 break;
8054 case OPC2_32_RRR1_MSUBR_Q_32_LL:
8055 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8056 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8057 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8058 break;
8059 case OPC2_32_RRR1_MSUBR_Q_32_UU:
8060 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8061 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8062 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8063 break;
8064 case OPC2_32_RRR1_MSUBRS_Q_32_LL:
8065 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
8066 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
8067 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8068 break;
8069 case OPC2_32_RRR1_MSUBRS_Q_32_UU:
8070 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
8071 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
8072 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
8073 break;
8074 default:
8075 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8077 tcg_temp_free(temp);
8078 tcg_temp_free(temp2);
8081 static void decode_rrr1_msubad_h(DisasContext *ctx)
8083 uint32_t op2;
8084 uint32_t r1, r2, r3, r4, n;
8086 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
8087 r1 = MASK_OP_RRR1_S1(ctx->opcode);
8088 r2 = MASK_OP_RRR1_S2(ctx->opcode);
8089 r3 = MASK_OP_RRR1_S3(ctx->opcode);
8090 r4 = MASK_OP_RRR1_D(ctx->opcode);
8091 n = MASK_OP_RRR1_N(ctx->opcode);
8093 switch (op2) {
8094 case OPC2_32_RRR1_MSUBAD_H_32_LL:
8095 CHECK_REG_PAIR(r4);
8096 CHECK_REG_PAIR(r3);
8097 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8098 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
8099 break;
8100 case OPC2_32_RRR1_MSUBAD_H_32_LU:
8101 CHECK_REG_PAIR(r4);
8102 CHECK_REG_PAIR(r3);
8103 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8104 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
8105 break;
8106 case OPC2_32_RRR1_MSUBAD_H_32_UL:
8107 CHECK_REG_PAIR(r4);
8108 CHECK_REG_PAIR(r3);
8109 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8110 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
8111 break;
8112 case OPC2_32_RRR1_MSUBAD_H_32_UU:
8113 CHECK_REG_PAIR(r4);
8114 CHECK_REG_PAIR(r3);
8115 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8116 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
8117 break;
8118 case OPC2_32_RRR1_MSUBADS_H_32_LL:
8119 CHECK_REG_PAIR(r4);
8120 CHECK_REG_PAIR(r3);
8121 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8122 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8123 n, MODE_LL);
8124 break;
8125 case OPC2_32_RRR1_MSUBADS_H_32_LU:
8126 CHECK_REG_PAIR(r4);
8127 CHECK_REG_PAIR(r3);
8128 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8129 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8130 n, MODE_LU);
8131 break;
8132 case OPC2_32_RRR1_MSUBADS_H_32_UL:
8133 CHECK_REG_PAIR(r4);
8134 CHECK_REG_PAIR(r3);
8135 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8136 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8137 n, MODE_UL);
8138 break;
8139 case OPC2_32_RRR1_MSUBADS_H_32_UU:
8140 CHECK_REG_PAIR(r4);
8141 CHECK_REG_PAIR(r3);
8142 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8143 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8144 n, MODE_UU);
8145 break;
8146 case OPC2_32_RRR1_MSUBADM_H_64_LL:
8147 CHECK_REG_PAIR(r4);
8148 CHECK_REG_PAIR(r3);
8149 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8150 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8151 n, MODE_LL);
8152 break;
8153 case OPC2_32_RRR1_MSUBADM_H_64_LU:
8154 CHECK_REG_PAIR(r4);
8155 CHECK_REG_PAIR(r3);
8156 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8157 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8158 n, MODE_LU);
8159 break;
8160 case OPC2_32_RRR1_MSUBADM_H_64_UL:
8161 CHECK_REG_PAIR(r4);
8162 CHECK_REG_PAIR(r3);
8163 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8164 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8165 n, MODE_UL);
8166 break;
8167 case OPC2_32_RRR1_MSUBADM_H_64_UU:
8168 CHECK_REG_PAIR(r4);
8169 CHECK_REG_PAIR(r3);
8170 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8171 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8172 n, MODE_UU);
8173 break;
8174 case OPC2_32_RRR1_MSUBADMS_H_64_LL:
8175 CHECK_REG_PAIR(r4);
8176 CHECK_REG_PAIR(r3);
8177 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8178 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8179 n, MODE_LL);
8180 break;
8181 case OPC2_32_RRR1_MSUBADMS_H_64_LU:
8182 CHECK_REG_PAIR(r4);
8183 CHECK_REG_PAIR(r3);
8184 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8185 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8186 n, MODE_LU);
8187 break;
8188 case OPC2_32_RRR1_MSUBADMS_H_64_UL:
8189 CHECK_REG_PAIR(r4);
8190 CHECK_REG_PAIR(r3);
8191 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8192 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8193 n, MODE_UL);
8194 break;
8195 case OPC2_32_RRR1_MSUBADMS_H_64_UU:
8196 CHECK_REG_PAIR(r4);
8197 CHECK_REG_PAIR(r3);
8198 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
8199 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
8200 n, MODE_UU);
8201 break;
8202 case OPC2_32_RRR1_MSUBADR_H_16_LL:
8203 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8204 cpu_gpr_d[r2], n, MODE_LL);
8205 break;
8206 case OPC2_32_RRR1_MSUBADR_H_16_LU:
8207 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8208 cpu_gpr_d[r2], n, MODE_LU);
8209 break;
8210 case OPC2_32_RRR1_MSUBADR_H_16_UL:
8211 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8212 cpu_gpr_d[r2], n, MODE_UL);
8213 break;
8214 case OPC2_32_RRR1_MSUBADR_H_16_UU:
8215 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8216 cpu_gpr_d[r2], n, MODE_UU);
8217 break;
8218 case OPC2_32_RRR1_MSUBADRS_H_16_LL:
8219 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8220 cpu_gpr_d[r2], n, MODE_LL);
8221 break;
8222 case OPC2_32_RRR1_MSUBADRS_H_16_LU:
8223 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8224 cpu_gpr_d[r2], n, MODE_LU);
8225 break;
8226 case OPC2_32_RRR1_MSUBADRS_H_16_UL:
8227 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8228 cpu_gpr_d[r2], n, MODE_UL);
8229 break;
8230 case OPC2_32_RRR1_MSUBADRS_H_16_UU:
8231 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
8232 cpu_gpr_d[r2], n, MODE_UU);
8233 break;
8234 default:
8235 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8239 /* RRRR format */
8240 static void decode_rrrr_extract_insert(DisasContext *ctx)
8242 uint32_t op2;
8243 int r1, r2, r3, r4;
8244 TCGv tmp_width, tmp_pos;
8246 r1 = MASK_OP_RRRR_S1(ctx->opcode);
8247 r2 = MASK_OP_RRRR_S2(ctx->opcode);
8248 r3 = MASK_OP_RRRR_S3(ctx->opcode);
8249 r4 = MASK_OP_RRRR_D(ctx->opcode);
8250 op2 = MASK_OP_RRRR_OP2(ctx->opcode);
8252 tmp_pos = tcg_temp_new();
8253 tmp_width = tcg_temp_new();
8255 switch (op2) {
8256 case OPC2_32_RRRR_DEXTR:
8257 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8258 if (r1 == r2) {
8259 tcg_gen_rotl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
8260 } else {
8261 tcg_gen_shl_tl(tmp_width, cpu_gpr_d[r1], tmp_pos);
8262 tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
8263 tcg_gen_shr_tl(tmp_pos, cpu_gpr_d[r2], tmp_pos);
8264 tcg_gen_or_tl(cpu_gpr_d[r4], tmp_width, tmp_pos);
8266 break;
8267 case OPC2_32_RRRR_EXTR:
8268 case OPC2_32_RRRR_EXTR_U:
8269 CHECK_REG_PAIR(r3);
8270 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
8271 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8272 tcg_gen_add_tl(tmp_pos, tmp_pos, tmp_width);
8273 tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
8274 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
8275 tcg_gen_subfi_tl(tmp_width, 32, tmp_width);
8276 if (op2 == OPC2_32_RRRR_EXTR) {
8277 tcg_gen_sar_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
8278 } else {
8279 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
8281 break;
8282 case OPC2_32_RRRR_INSERT:
8283 CHECK_REG_PAIR(r3);
8284 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
8285 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
8286 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], tmp_width,
8287 tmp_pos);
8288 break;
8289 default:
8290 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8292 tcg_temp_free(tmp_pos);
8293 tcg_temp_free(tmp_width);
8296 /* RRRW format */
8297 static void decode_rrrw_extract_insert(DisasContext *ctx)
8299 uint32_t op2;
8300 int r1, r2, r3, r4;
8301 int32_t width;
8303 TCGv temp, temp2;
8305 op2 = MASK_OP_RRRW_OP2(ctx->opcode);
8306 r1 = MASK_OP_RRRW_S1(ctx->opcode);
8307 r2 = MASK_OP_RRRW_S2(ctx->opcode);
8308 r3 = MASK_OP_RRRW_S3(ctx->opcode);
8309 r4 = MASK_OP_RRRW_D(ctx->opcode);
8310 width = MASK_OP_RRRW_WIDTH(ctx->opcode);
8312 temp = tcg_temp_new();
8314 switch (op2) {
8315 case OPC2_32_RRRW_EXTR:
8316 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8317 tcg_gen_addi_tl(temp, temp, width);
8318 tcg_gen_subfi_tl(temp, 32, temp);
8319 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
8320 tcg_gen_sari_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], 32 - width);
8321 break;
8322 case OPC2_32_RRRW_EXTR_U:
8323 if (width == 0) {
8324 tcg_gen_movi_tl(cpu_gpr_d[r4], 0);
8325 } else {
8326 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8327 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
8328 tcg_gen_andi_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], ~0u >> (32-width));
8330 break;
8331 case OPC2_32_RRRW_IMASK:
8332 temp2 = tcg_temp_new();
8334 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
8335 tcg_gen_movi_tl(temp2, (1 << width) - 1);
8336 tcg_gen_shl_tl(temp2, temp2, temp);
8337 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r2], temp);
8338 tcg_gen_mov_tl(cpu_gpr_d[r4+1], temp2);
8340 tcg_temp_free(temp2);
8341 break;
8342 case OPC2_32_RRRW_INSERT:
8343 temp2 = tcg_temp_new();
8345 tcg_gen_movi_tl(temp, width);
8346 tcg_gen_andi_tl(temp2, cpu_gpr_d[r3], 0x1f);
8347 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], temp, temp2);
8349 tcg_temp_free(temp2);
8350 break;
8351 default:
8352 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8354 tcg_temp_free(temp);
8357 /* SYS Format*/
8358 static void decode_sys_interrupts(DisasContext *ctx)
8360 uint32_t op2;
8361 uint32_t r1;
8362 TCGLabel *l1;
8363 TCGv tmp;
8365 op2 = MASK_OP_SYS_OP2(ctx->opcode);
8366 r1 = MASK_OP_SYS_S1D(ctx->opcode);
8368 switch (op2) {
8369 case OPC2_32_SYS_DEBUG:
8370 /* raise EXCP_DEBUG */
8371 break;
8372 case OPC2_32_SYS_DISABLE:
8373 tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~MASK_ICR_IE_1_3);
8374 break;
8375 case OPC2_32_SYS_DSYNC:
8376 break;
8377 case OPC2_32_SYS_ENABLE:
8378 tcg_gen_ori_tl(cpu_ICR, cpu_ICR, MASK_ICR_IE_1_3);
8379 break;
8380 case OPC2_32_SYS_ISYNC:
8381 break;
8382 case OPC2_32_SYS_NOP:
8383 break;
8384 case OPC2_32_SYS_RET:
8385 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
8386 break;
8387 case OPC2_32_SYS_FRET:
8388 gen_fret(ctx);
8389 break;
8390 case OPC2_32_SYS_RFE:
8391 gen_helper_rfe(cpu_env);
8392 tcg_gen_exit_tb(NULL, 0);
8393 ctx->base.is_jmp = DISAS_NORETURN;
8394 break;
8395 case OPC2_32_SYS_RFM:
8396 if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
8397 tmp = tcg_temp_new();
8398 l1 = gen_new_label();
8400 tcg_gen_ld32u_tl(tmp, cpu_env, offsetof(CPUTriCoreState, DBGSR));
8401 tcg_gen_andi_tl(tmp, tmp, MASK_DBGSR_DE);
8402 tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1);
8403 gen_helper_rfm(cpu_env);
8404 gen_set_label(l1);
8405 tcg_gen_exit_tb(NULL, 0);
8406 ctx->base.is_jmp = DISAS_NORETURN;
8407 tcg_temp_free(tmp);
8408 } else {
8409 /* generate privilege trap */
8411 break;
8412 case OPC2_32_SYS_RSLCX:
8413 gen_helper_rslcx(cpu_env);
8414 break;
8415 case OPC2_32_SYS_SVLCX:
8416 gen_helper_svlcx(cpu_env);
8417 break;
8418 case OPC2_32_SYS_RESTORE:
8419 if (has_feature(ctx, TRICORE_FEATURE_16)) {
8420 if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
8421 (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
8422 tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
8423 } /* else raise privilege trap */
8424 } else {
8425 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8427 break;
8428 case OPC2_32_SYS_TRAPSV:
8429 l1 = gen_new_label();
8430 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_SV, 0, l1);
8431 generate_trap(ctx, TRAPC_ASSERT, TIN5_SOVF);
8432 gen_set_label(l1);
8433 break;
8434 case OPC2_32_SYS_TRAPV:
8435 l1 = gen_new_label();
8436 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_V, 0, l1);
8437 generate_trap(ctx, TRAPC_ASSERT, TIN5_OVF);
8438 gen_set_label(l1);
8439 break;
8440 default:
8441 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8445 static void decode_32Bit_opc(DisasContext *ctx)
8447 int op1;
8448 int32_t r1, r2, r3;
8449 int32_t address, const16;
8450 int8_t b, const4;
8451 int32_t bpos;
8452 TCGv temp, temp2, temp3;
8454 op1 = MASK_OP_MAJOR(ctx->opcode);
8456 /* handle JNZ.T opcode only being 7 bit long */
8457 if (unlikely((op1 & 0x7f) == OPCM_32_BRN_JTT)) {
8458 op1 = OPCM_32_BRN_JTT;
8461 switch (op1) {
8462 /* ABS-format */
8463 case OPCM_32_ABS_LDW:
8464 decode_abs_ldw(ctx);
8465 break;
8466 case OPCM_32_ABS_LDB:
8467 decode_abs_ldb(ctx);
8468 break;
8469 case OPCM_32_ABS_LDMST_SWAP:
8470 decode_abs_ldst_swap(ctx);
8471 break;
8472 case OPCM_32_ABS_LDST_CONTEXT:
8473 decode_abs_ldst_context(ctx);
8474 break;
8475 case OPCM_32_ABS_STORE:
8476 decode_abs_store(ctx);
8477 break;
8478 case OPCM_32_ABS_STOREB_H:
8479 decode_abs_storeb_h(ctx);
8480 break;
8481 case OPC1_32_ABS_STOREQ:
8482 address = MASK_OP_ABS_OFF18(ctx->opcode);
8483 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8484 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8485 temp2 = tcg_temp_new();
8487 tcg_gen_shri_tl(temp2, cpu_gpr_d[r1], 16);
8488 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_LEUW);
8490 tcg_temp_free(temp2);
8491 tcg_temp_free(temp);
8492 break;
8493 case OPC1_32_ABS_LD_Q:
8494 address = MASK_OP_ABS_OFF18(ctx->opcode);
8495 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8496 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8498 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
8499 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
8501 tcg_temp_free(temp);
8502 break;
8503 case OPC1_32_ABS_LEA:
8504 address = MASK_OP_ABS_OFF18(ctx->opcode);
8505 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8506 tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address));
8507 break;
8508 /* ABSB-format */
8509 case OPC1_32_ABSB_ST_T:
8510 address = MASK_OP_ABS_OFF18(ctx->opcode);
8511 b = MASK_OP_ABSB_B(ctx->opcode);
8512 bpos = MASK_OP_ABSB_BPOS(ctx->opcode);
8514 temp = tcg_const_i32(EA_ABS_FORMAT(address));
8515 temp2 = tcg_temp_new();
8517 tcg_gen_qemu_ld_tl(temp2, temp, ctx->mem_idx, MO_UB);
8518 tcg_gen_andi_tl(temp2, temp2, ~(0x1u << bpos));
8519 tcg_gen_ori_tl(temp2, temp2, (b << bpos));
8520 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_UB);
8522 tcg_temp_free(temp);
8523 tcg_temp_free(temp2);
8524 break;
8525 /* B-format */
8526 case OPC1_32_B_CALL:
8527 case OPC1_32_B_CALLA:
8528 case OPC1_32_B_FCALL:
8529 case OPC1_32_B_FCALLA:
8530 case OPC1_32_B_J:
8531 case OPC1_32_B_JA:
8532 case OPC1_32_B_JL:
8533 case OPC1_32_B_JLA:
8534 address = MASK_OP_B_DISP24_SEXT(ctx->opcode);
8535 gen_compute_branch(ctx, op1, 0, 0, 0, address);
8536 break;
8537 /* Bit-format */
8538 case OPCM_32_BIT_ANDACC:
8539 decode_bit_andacc(ctx);
8540 break;
8541 case OPCM_32_BIT_LOGICAL_T1:
8542 decode_bit_logical_t(ctx);
8543 break;
8544 case OPCM_32_BIT_INSERT:
8545 decode_bit_insert(ctx);
8546 break;
8547 case OPCM_32_BIT_LOGICAL_T2:
8548 decode_bit_logical_t2(ctx);
8549 break;
8550 case OPCM_32_BIT_ORAND:
8551 decode_bit_orand(ctx);
8552 break;
8553 case OPCM_32_BIT_SH_LOGIC1:
8554 decode_bit_sh_logic1(ctx);
8555 break;
8556 case OPCM_32_BIT_SH_LOGIC2:
8557 decode_bit_sh_logic2(ctx);
8558 break;
8559 /* BO Format */
8560 case OPCM_32_BO_ADDRMODE_POST_PRE_BASE:
8561 decode_bo_addrmode_post_pre_base(ctx);
8562 break;
8563 case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR:
8564 decode_bo_addrmode_bitreverse_circular(ctx);
8565 break;
8566 case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE:
8567 decode_bo_addrmode_ld_post_pre_base(ctx);
8568 break;
8569 case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR:
8570 decode_bo_addrmode_ld_bitreverse_circular(ctx);
8571 break;
8572 case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE:
8573 decode_bo_addrmode_stctx_post_pre_base(ctx);
8574 break;
8575 case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
8576 decode_bo_addrmode_ldmst_bitreverse_circular(ctx);
8577 break;
8578 /* BOL-format */
8579 case OPC1_32_BOL_LD_A_LONGOFF:
8580 case OPC1_32_BOL_LD_W_LONGOFF:
8581 case OPC1_32_BOL_LEA_LONGOFF:
8582 case OPC1_32_BOL_ST_W_LONGOFF:
8583 case OPC1_32_BOL_ST_A_LONGOFF:
8584 case OPC1_32_BOL_LD_B_LONGOFF:
8585 case OPC1_32_BOL_LD_BU_LONGOFF:
8586 case OPC1_32_BOL_LD_H_LONGOFF:
8587 case OPC1_32_BOL_LD_HU_LONGOFF:
8588 case OPC1_32_BOL_ST_B_LONGOFF:
8589 case OPC1_32_BOL_ST_H_LONGOFF:
8590 decode_bol_opc(ctx, op1);
8591 break;
8592 /* BRC Format */
8593 case OPCM_32_BRC_EQ_NEQ:
8594 case OPCM_32_BRC_GE:
8595 case OPCM_32_BRC_JLT:
8596 case OPCM_32_BRC_JNE:
8597 const4 = MASK_OP_BRC_CONST4_SEXT(ctx->opcode);
8598 address = MASK_OP_BRC_DISP15_SEXT(ctx->opcode);
8599 r1 = MASK_OP_BRC_S1(ctx->opcode);
8600 gen_compute_branch(ctx, op1, r1, 0, const4, address);
8601 break;
8602 /* BRN Format */
8603 case OPCM_32_BRN_JTT:
8604 address = MASK_OP_BRN_DISP15_SEXT(ctx->opcode);
8605 r1 = MASK_OP_BRN_S1(ctx->opcode);
8606 gen_compute_branch(ctx, op1, r1, 0, 0, address);
8607 break;
8608 /* BRR Format */
8609 case OPCM_32_BRR_EQ_NEQ:
8610 case OPCM_32_BRR_ADDR_EQ_NEQ:
8611 case OPCM_32_BRR_GE:
8612 case OPCM_32_BRR_JLT:
8613 case OPCM_32_BRR_JNE:
8614 case OPCM_32_BRR_JNZ:
8615 case OPCM_32_BRR_LOOP:
8616 address = MASK_OP_BRR_DISP15_SEXT(ctx->opcode);
8617 r2 = MASK_OP_BRR_S2(ctx->opcode);
8618 r1 = MASK_OP_BRR_S1(ctx->opcode);
8619 gen_compute_branch(ctx, op1, r1, r2, 0, address);
8620 break;
8621 /* RC Format */
8622 case OPCM_32_RC_LOGICAL_SHIFT:
8623 decode_rc_logical_shift(ctx);
8624 break;
8625 case OPCM_32_RC_ACCUMULATOR:
8626 decode_rc_accumulator(ctx);
8627 break;
8628 case OPCM_32_RC_SERVICEROUTINE:
8629 decode_rc_serviceroutine(ctx);
8630 break;
8631 case OPCM_32_RC_MUL:
8632 decode_rc_mul(ctx);
8633 break;
8634 /* RCPW Format */
8635 case OPCM_32_RCPW_MASK_INSERT:
8636 decode_rcpw_insert(ctx);
8637 break;
8638 /* RCRR Format */
8639 case OPC1_32_RCRR_INSERT:
8640 r1 = MASK_OP_RCRR_S1(ctx->opcode);
8641 r2 = MASK_OP_RCRR_S3(ctx->opcode);
8642 r3 = MASK_OP_RCRR_D(ctx->opcode);
8643 const16 = MASK_OP_RCRR_CONST4(ctx->opcode);
8644 temp = tcg_const_i32(const16);
8645 temp2 = tcg_temp_new(); /* width*/
8646 temp3 = tcg_temp_new(); /* pos */
8648 CHECK_REG_PAIR(r3);
8650 tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
8651 tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
8653 gen_insert(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, temp2, temp3);
8655 tcg_temp_free(temp);
8656 tcg_temp_free(temp2);
8657 tcg_temp_free(temp3);
8658 break;
8659 /* RCRW Format */
8660 case OPCM_32_RCRW_MASK_INSERT:
8661 decode_rcrw_insert(ctx);
8662 break;
8663 /* RCR Format */
8664 case OPCM_32_RCR_COND_SELECT:
8665 decode_rcr_cond_select(ctx);
8666 break;
8667 case OPCM_32_RCR_MADD:
8668 decode_rcr_madd(ctx);
8669 break;
8670 case OPCM_32_RCR_MSUB:
8671 decode_rcr_msub(ctx);
8672 break;
8673 /* RLC Format */
8674 case OPC1_32_RLC_ADDI:
8675 case OPC1_32_RLC_ADDIH:
8676 case OPC1_32_RLC_ADDIH_A:
8677 case OPC1_32_RLC_MFCR:
8678 case OPC1_32_RLC_MOV:
8679 case OPC1_32_RLC_MOV_64:
8680 case OPC1_32_RLC_MOV_U:
8681 case OPC1_32_RLC_MOV_H:
8682 case OPC1_32_RLC_MOVH_A:
8683 case OPC1_32_RLC_MTCR:
8684 decode_rlc_opc(ctx, op1);
8685 break;
8686 /* RR Format */
8687 case OPCM_32_RR_ACCUMULATOR:
8688 decode_rr_accumulator(ctx);
8689 break;
8690 case OPCM_32_RR_LOGICAL_SHIFT:
8691 decode_rr_logical_shift(ctx);
8692 break;
8693 case OPCM_32_RR_ADDRESS:
8694 decode_rr_address(ctx);
8695 break;
8696 case OPCM_32_RR_IDIRECT:
8697 decode_rr_idirect(ctx);
8698 break;
8699 case OPCM_32_RR_DIVIDE:
8700 decode_rr_divide(ctx);
8701 break;
8702 /* RR1 Format */
8703 case OPCM_32_RR1_MUL:
8704 decode_rr1_mul(ctx);
8705 break;
8706 case OPCM_32_RR1_MULQ:
8707 decode_rr1_mulq(ctx);
8708 break;
8709 /* RR2 format */
8710 case OPCM_32_RR2_MUL:
8711 decode_rr2_mul(ctx);
8712 break;
8713 /* RRPW format */
8714 case OPCM_32_RRPW_EXTRACT_INSERT:
8715 decode_rrpw_extract_insert(ctx);
8716 break;
8717 case OPC1_32_RRPW_DEXTR:
8718 r1 = MASK_OP_RRPW_S1(ctx->opcode);
8719 r2 = MASK_OP_RRPW_S2(ctx->opcode);
8720 r3 = MASK_OP_RRPW_D(ctx->opcode);
8721 const16 = MASK_OP_RRPW_POS(ctx->opcode);
8722 if (r1 == r2) {
8723 tcg_gen_rotli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], const16);
8724 } else {
8725 temp = tcg_temp_new();
8726 tcg_gen_shli_tl(temp, cpu_gpr_d[r1], const16);
8727 tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], 32 - const16);
8728 tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
8729 tcg_temp_free(temp);
8731 break;
8732 /* RRR Format */
8733 case OPCM_32_RRR_COND_SELECT:
8734 decode_rrr_cond_select(ctx);
8735 break;
8736 case OPCM_32_RRR_DIVIDE:
8737 decode_rrr_divide(ctx);
8738 break;
8739 /* RRR2 Format */
8740 case OPCM_32_RRR2_MADD:
8741 decode_rrr2_madd(ctx);
8742 break;
8743 case OPCM_32_RRR2_MSUB:
8744 decode_rrr2_msub(ctx);
8745 break;
8746 /* RRR1 format */
8747 case OPCM_32_RRR1_MADD:
8748 decode_rrr1_madd(ctx);
8749 break;
8750 case OPCM_32_RRR1_MADDQ_H:
8751 decode_rrr1_maddq_h(ctx);
8752 break;
8753 case OPCM_32_RRR1_MADDSU_H:
8754 decode_rrr1_maddsu_h(ctx);
8755 break;
8756 case OPCM_32_RRR1_MSUB_H:
8757 decode_rrr1_msub(ctx);
8758 break;
8759 case OPCM_32_RRR1_MSUB_Q:
8760 decode_rrr1_msubq_h(ctx);
8761 break;
8762 case OPCM_32_RRR1_MSUBAD_H:
8763 decode_rrr1_msubad_h(ctx);
8764 break;
8765 /* RRRR format */
8766 case OPCM_32_RRRR_EXTRACT_INSERT:
8767 decode_rrrr_extract_insert(ctx);
8768 break;
8769 /* RRRW format */
8770 case OPCM_32_RRRW_EXTRACT_INSERT:
8771 decode_rrrw_extract_insert(ctx);
8772 break;
8773 /* SYS format */
8774 case OPCM_32_SYS_INTERRUPTS:
8775 decode_sys_interrupts(ctx);
8776 break;
8777 case OPC1_32_SYS_RSTV:
8778 tcg_gen_movi_tl(cpu_PSW_V, 0);
8779 tcg_gen_mov_tl(cpu_PSW_SV, cpu_PSW_V);
8780 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
8781 tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V);
8782 break;
8783 default:
8784 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8788 static bool tricore_insn_is_16bit(uint32_t insn)
8790 return (insn & 0x1) == 0;
8793 static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
8794 CPUState *cs)
8796 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8797 CPUTriCoreState *env = cs->env_ptr;
8798 ctx->mem_idx = cpu_mmu_index(env, false);
8799 ctx->hflags = (uint32_t)ctx->base.tb->flags;
8800 ctx->features = env->features;
8803 static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8807 static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8809 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8811 tcg_gen_insn_start(ctx->base.pc_next);
8814 static bool tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8815 const CPUBreakpoint *bp)
8817 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8818 generate_qemu_excp(ctx, EXCP_DEBUG);
8820 * The address covered by the breakpoint must be included in
8821 * [tb->pc, tb->pc + tb->size) in order to for it to be
8822 * properly cleared -- thus we increment the PC here so that
8823 * the logic setting tb->size below does the right thing.
8825 ctx->base.pc_next += 4;
8826 return true;
8829 static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx)
8832 * Return true if the insn at ctx->base.pc_next might cross a page boundary.
8833 * (False positives are OK, false negatives are not.)
8834 * Our caller ensures we are only called if dc->base.pc_next is less than
8835 * 4 bytes from the page boundary, so we cross the page if the first
8836 * 16 bits indicate that this is a 32 bit insn.
8838 uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next);
8840 return !tricore_insn_is_16bit(insn);
8844 static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8846 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8847 CPUTriCoreState *env = cpu->env_ptr;
8848 uint16_t insn_lo;
8849 bool is_16bit;
8851 insn_lo = cpu_lduw_code(env, ctx->base.pc_next);
8852 is_16bit = tricore_insn_is_16bit(insn_lo);
8853 if (is_16bit) {
8854 ctx->opcode = insn_lo;
8855 ctx->pc_succ_insn = ctx->base.pc_next + 2;
8856 decode_16Bit_opc(ctx);
8857 } else {
8858 uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2);
8859 ctx->opcode = insn_hi << 16 | insn_lo;
8860 ctx->pc_succ_insn = ctx->base.pc_next + 4;
8861 decode_32Bit_opc(ctx);
8863 ctx->base.pc_next = ctx->pc_succ_insn;
8865 if (ctx->base.is_jmp == DISAS_NEXT) {
8866 target_ulong page_start;
8868 page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
8869 if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE
8870 || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3
8871 && insn_crosses_page(env, ctx))) {
8872 ctx->base.is_jmp = DISAS_TOO_MANY;
8877 static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8879 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8881 switch (ctx->base.is_jmp) {
8882 case DISAS_TOO_MANY:
8883 gen_goto_tb(ctx, 0, ctx->base.pc_next);
8884 break;
8885 case DISAS_NORETURN:
8886 break;
8887 default:
8888 g_assert_not_reached();
8892 static void tricore_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
8894 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
8895 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
8898 static const TranslatorOps tricore_tr_ops = {
8899 .init_disas_context = tricore_tr_init_disas_context,
8900 .tb_start = tricore_tr_tb_start,
8901 .insn_start = tricore_tr_insn_start,
8902 .breakpoint_check = tricore_tr_breakpoint_check,
8903 .translate_insn = tricore_tr_translate_insn,
8904 .tb_stop = tricore_tr_tb_stop,
8905 .disas_log = tricore_tr_disas_log,
8909 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
8911 DisasContext ctx;
8912 translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns);
8915 void
8916 restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb,
8917 target_ulong *data)
8919 env->PC = data[0];
8923 * Initialization
8927 void cpu_state_reset(CPUTriCoreState *env)
8929 /* Reset Regs to Default Value */
8930 env->PSW = 0xb80;
8931 fpu_set_state(env);
8934 static void tricore_tcg_init_csfr(void)
8936 cpu_PCXI = tcg_global_mem_new(cpu_env,
8937 offsetof(CPUTriCoreState, PCXI), "PCXI");
8938 cpu_PSW = tcg_global_mem_new(cpu_env,
8939 offsetof(CPUTriCoreState, PSW), "PSW");
8940 cpu_PC = tcg_global_mem_new(cpu_env,
8941 offsetof(CPUTriCoreState, PC), "PC");
8942 cpu_ICR = tcg_global_mem_new(cpu_env,
8943 offsetof(CPUTriCoreState, ICR), "ICR");
8946 void tricore_tcg_init(void)
8948 int i;
8950 /* reg init */
8951 for (i = 0 ; i < 16 ; i++) {
8952 cpu_gpr_a[i] = tcg_global_mem_new(cpu_env,
8953 offsetof(CPUTriCoreState, gpr_a[i]),
8954 regnames_a[i]);
8956 for (i = 0 ; i < 16 ; i++) {
8957 cpu_gpr_d[i] = tcg_global_mem_new(cpu_env,
8958 offsetof(CPUTriCoreState, gpr_d[i]),
8959 regnames_d[i]);
8961 tricore_tcg_init_csfr();
8962 /* init PSW flag cache */
8963 cpu_PSW_C = tcg_global_mem_new(cpu_env,
8964 offsetof(CPUTriCoreState, PSW_USB_C),
8965 "PSW_C");
8966 cpu_PSW_V = tcg_global_mem_new(cpu_env,
8967 offsetof(CPUTriCoreState, PSW_USB_V),
8968 "PSW_V");
8969 cpu_PSW_SV = tcg_global_mem_new(cpu_env,
8970 offsetof(CPUTriCoreState, PSW_USB_SV),
8971 "PSW_SV");
8972 cpu_PSW_AV = tcg_global_mem_new(cpu_env,
8973 offsetof(CPUTriCoreState, PSW_USB_AV),
8974 "PSW_AV");
8975 cpu_PSW_SAV = tcg_global_mem_new(cpu_env,
8976 offsetof(CPUTriCoreState, PSW_USB_SAV),
8977 "PSW_SAV");