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