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