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