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 "exec/exec-all.h"
24 #include "tcg/tcg-op.h"
25 #include "exec/cpu_ldst.h"
26 #include "qemu/qemu-print.h"
27
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30
31 #include "tricore-opcodes.h"
32 #include "exec/translator.h"
33 #include "exec/log.h"
34
35 #define HELPER_H "helper.h"
36 #include "exec/helper-info.c.inc"
37 #undef HELPER_H
38
39 #define DISAS_EXIT DISAS_TARGET_0
40 #define DISAS_EXIT_UPDATE DISAS_TARGET_1
41 #define DISAS_JUMP DISAS_TARGET_2
42
43 /*
44 * TCG registers
45 */
46 static TCGv cpu_PC;
47 static TCGv cpu_PCXI;
48 static TCGv cpu_PSW;
49 static TCGv cpu_ICR;
50 /* GPR registers */
51 static TCGv cpu_gpr_a[16];
52 static TCGv cpu_gpr_d[16];
53 /* PSW Flag cache */
54 static TCGv cpu_PSW_C;
55 static TCGv cpu_PSW_V;
56 static TCGv cpu_PSW_SV;
57 static TCGv cpu_PSW_AV;
58 static TCGv cpu_PSW_SAV;
59
60 static const char *regnames_a[] = {
61 "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
62 "a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
63 "a12" , "a13" , "a14" , "a15",
64 };
65
66 static const char *regnames_d[] = {
67 "d0" , "d1" , "d2" , "d3" , "d4" , "d5" ,
68 "d6" , "d7" , "d8" , "d9" , "d10" , "d11" ,
69 "d12" , "d13" , "d14" , "d15",
70 };
71
72 typedef struct DisasContext {
73 DisasContextBase base;
74 target_ulong pc_succ_insn;
75 uint32_t opcode;
76 /* Routine used to access memory */
77 int mem_idx;
78 int priv;
79 uint64_t features;
80 uint32_t icr_ie_mask, icr_ie_offset;
81 } DisasContext;
82
has_feature(DisasContext * ctx,int feature)83 static int has_feature(DisasContext *ctx, int feature)
84 {
85 return (ctx->features & (1ULL << feature)) != 0;
86 }
87
88 enum {
89 MODE_LL = 0,
90 MODE_LU = 1,
91 MODE_UL = 2,
92 MODE_UU = 3,
93 };
94
tricore_cpu_dump_state(CPUState * cs,FILE * f,int flags)95 void tricore_cpu_dump_state(CPUState *cs, FILE *f, int flags)
96 {
97 CPUTriCoreState *env = cpu_env(cs);
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 /* Macros 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(tcg_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, tcg_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
gen_offset_ld(DisasContext * ctx,TCGv r1,TCGv r2,int16_t con,MemOp mop)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
gen_offset_st(DisasContext * ctx,TCGv r1,TCGv r2,int16_t con,MemOp mop)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
gen_st_2regs_64(TCGv rh,TCGv rl,TCGv address,DisasContext * ctx)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
gen_offset_st_2regs(TCGv rh,TCGv rl,TCGv base,int16_t con,DisasContext * ctx)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
gen_ld_2regs_64(TCGv rh,TCGv rl,TCGv address,DisasContext * ctx)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
gen_offset_ld_2regs(TCGv rh,TCGv rl,TCGv base,int16_t con,DisasContext * ctx)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
gen_st_preincr(DisasContext * ctx,TCGv r1,TCGv r2,int16_t off,MemOp mop)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
gen_ld_preincr(DisasContext * ctx,TCGv r1,TCGv r2,int16_t off,MemOp mop)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]); */
gen_ldmst(DisasContext * ctx,int ereg,TCGv ea)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];*/
gen_swap(DisasContext * ctx,int reg,TCGv ea)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
gen_cmpswap(DisasContext * ctx,int reg,TCGv ea)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
gen_swapmsk(DisasContext * ctx,int reg,TCGv ea)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 /* We generate loads and store to core special function register (csfr) through
336 the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
337 macros R, A and E, which allow read-only, all and endinit protected access.
338 These macros also specify in which ISA version the csfr was introduced. */
339 #define R(ADDRESS, REG, FEATURE) \
340 case ADDRESS: \
341 if (has_feature(ctx, FEATURE)) { \
342 tcg_gen_ld_tl(ret, tcg_env, offsetof(CPUTriCoreState, REG)); \
343 } \
344 break;
345 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
346 #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
gen_mfcr(DisasContext * ctx,TCGv ret,int32_t offset)347 static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset)
348 {
349 /* since we're caching PSW make this a special case */
350 if (offset == 0xfe04) {
351 gen_helper_psw_read(ret, tcg_env);
352 } else {
353 switch (offset) {
354 #include "csfr.h.inc"
355 }
356 }
357 }
358 #undef R
359 #undef A
360 #undef E
361
362 #define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
363 since no exception occurs */
364 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
365 case ADDRESS: \
366 if (has_feature(ctx, FEATURE)) { \
367 tcg_gen_st_tl(r1, tcg_env, offsetof(CPUTriCoreState, REG)); \
368 } \
369 break;
370 /* Endinit protected registers
371 TODO: Since the endinit bit is in a register of a not yet implemented
372 watchdog device, we handle endinit protected registers like
373 all-access registers for now. */
374 #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
gen_mtcr(DisasContext * ctx,TCGv r1,int32_t offset)375 static inline void gen_mtcr(DisasContext *ctx, TCGv r1,
376 int32_t offset)
377 {
378 if (ctx->priv == TRICORE_PRIV_SM) {
379 /* since we're caching PSW make this a special case */
380 if (offset == 0xfe04) {
381 gen_helper_psw_write(tcg_env, r1);
382 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
383 } else {
384 switch (offset) {
385 #include "csfr.h.inc"
386 }
387 }
388 } else {
389 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
390 }
391 }
392
393 /* Functions for arithmetic instructions */
394
gen_add_d(TCGv ret,TCGv r1,TCGv r2)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
gen_add64_d(TCGv_i64 ret,TCGv_i64 r1,TCGv_i64 r2)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
gen_addsub64_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,void (* op1)(TCGv,TCGv,TCGv),void (* op2)(TCGv,TCGv,TCGv))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); */
gen_madd32_d(TCGv ret,TCGv r1,TCGv r2,TCGv 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
gen_maddi32_d(TCGv ret,TCGv r1,TCGv r2,int32_t con)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
gen_madd64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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
gen_maddu64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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
gen_maddi64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_maddui64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_madd_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsu_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsum_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_madds_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsus_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsums_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64_2, temp64);
790 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
791 }
792
793
794 static inline void
gen_maddm_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddms_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64_2, temp64);
845 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
846 }
847
848 static inline void
gen_maddr64_h(TCGv ret,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, r1_low, r1_high);
869 }
870
871 static inline void
gen_maddr32_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsur32_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, temp, temp2);
906 }
907
908
909 static inline void
gen_maddr64s_h(TCGv ret,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, r1_low, r1_high);
930 }
931
932 static inline void
gen_maddr32s_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_maddsur32s_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, temp, temp2);
967 }
968
969 static inline void
gen_maddr_q(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n)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, tcg_env, r1, r2, r3, t_n);
974 }
975
976 static inline void
gen_maddrs_q(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n)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, tcg_env, r1, r2, r3, t_n);
981 }
982
983 static inline void
gen_madd32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n,uint32_t up_shift)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
gen_m16add32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16adds32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16add64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16adds64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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, tcg_env, t1, t2);
1117 tcg_gen_extr_i64_i32(rl, rh, t1);
1118 }
1119
1120 static inline void
gen_madd64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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
gen_madds32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n,uint32_t up_shift)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, tcg_env, t1, t2);
1184 }
1185
1186 static inline void
gen_madds64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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, tcg_env, r1, arg2, arg3, t_n);
1195 tcg_gen_extr_i64_i32(rl, rh, r1);
1196 }
1197
1198 /* ret = r2 - (r1 * r3); */
gen_msub32_d(TCGv ret,TCGv r1,TCGv r2,TCGv 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
gen_msubi32_d(TCGv ret,TCGv r1,TCGv r2,int32_t con)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
gen_msub64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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
gen_msubi64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_msubu64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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
gen_msubui64_d(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_addi_d(TCGv ret,TCGv r1,target_ulong r2)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 */
gen_add_CC(TCGv ret,TCGv r1,TCGv r2)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
gen_addi_CC(TCGv ret,TCGv r1,int32_t con)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
gen_addc_CC(TCGv ret,TCGv r1,TCGv r2)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
gen_addci_CC(TCGv ret,TCGv r1,int32_t con)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
gen_cond_add(TCGCond cond,TCGv r1,TCGv r2,TCGv r3,TCGv r4)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
gen_condi_add(TCGCond cond,TCGv r1,int32_t r2,TCGv r3,TCGv r4)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
gen_sub_d(TCGv ret,TCGv r1,TCGv r2)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
gen_sub64_d(TCGv_i64 ret,TCGv_i64 r1,TCGv_i64 r2)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
gen_sub_CC(TCGv ret,TCGv r1,TCGv r2)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
gen_subc_CC(TCGv ret,TCGv r1,TCGv r2)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
gen_cond_sub(TCGCond cond,TCGv r1,TCGv r2,TCGv r3,TCGv r4)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
gen_msub_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubs_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubm_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubms_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64_2, temp64);
1640 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
1641 }
1642
1643 static inline void
gen_msubr64_h(TCGv ret,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, r1_low, r1_high);
1664 }
1665
1666 static inline void
gen_msubr32_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubr64s_h(TCGv ret,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, r1_low, r1_high);
1698 }
1699
1700 static inline void
gen_msubr32s_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubr_q(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n)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, tcg_env, r1, r2, r3, temp);
1716 }
1717
1718 static inline void
gen_msubrs_q(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n)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, tcg_env, r1, r2, r3, temp);
1723 }
1724
1725 static inline void
gen_msub32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n,uint32_t up_shift)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
gen_m16sub32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16subs32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16sub64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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
gen_m16subs64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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, tcg_env, t1, t2);
1850 tcg_gen_extr_i64_i32(rl, rh, t1);
1851 }
1852
1853 static inline void
gen_msub64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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
gen_msubs32_q(TCGv ret,TCGv arg1,TCGv arg2,TCGv arg3,uint32_t n,uint32_t up_shift)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, tcg_env, t1, t3);
1922 }
1923
1924 static inline void
gen_msubs64_q(TCGv rl,TCGv rh,TCGv arg1_low,TCGv arg1_high,TCGv arg2,TCGv arg3,uint32_t n)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, tcg_env, r1, arg2, arg3, t_n);
1933 tcg_gen_extr_i64_i32(rl, rh, r1);
1934 }
1935
1936 static inline void
gen_msubad_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubadm_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubadr32_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, temp, temp2);
2020 }
2021
2022 static inline void
gen_msubads_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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
gen_msubadms_h(TCGv ret_low,TCGv ret_high,TCGv r1_low,TCGv r1_high,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64_2, temp64);
2086 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2087 }
2088
2089 static inline void
gen_msubadr32s_h(TCGv ret,TCGv r1,TCGv r2,TCGv r3,uint32_t n,uint32_t mode)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, tcg_env, temp64, temp, temp2);
2113 }
2114
gen_abs(TCGv ret,TCGv r1)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
gen_absdif(TCGv ret,TCGv r1,TCGv r2)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
gen_absdifi(TCGv ret,TCGv r1,int32_t con)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
gen_absdifsi(TCGv ret,TCGv r1,int32_t con)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, tcg_env, r1, temp);
2166 }
2167
gen_mul_i32s(TCGv ret,TCGv r1,TCGv r2)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
gen_muli_i32s(TCGv ret,TCGv r1,int32_t con)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
gen_mul_i64s(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2)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
gen_muli_i64s(TCGv ret_low,TCGv ret_high,TCGv r1,int32_t con)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
gen_mul_i64u(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2)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
gen_muli_i64u(TCGv ret_low,TCGv ret_high,TCGv r1,int32_t con)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
gen_mulsi_i32(TCGv ret,TCGv r1,int32_t con)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, tcg_env, r1, temp);
2240 }
2241
gen_mulsui_i32(TCGv ret,TCGv r1,int32_t con)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, tcg_env, r1, temp);
2246 }
2247
2248 /* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
gen_maddsi_32(TCGv ret,TCGv r1,TCGv r2,int32_t con)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, tcg_env, r1, r2, temp);
2253 }
2254
gen_maddsui_32(TCGv ret,TCGv r1,TCGv r2,int32_t con)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, tcg_env, r1, r2, temp);
2259 }
2260
2261 static void
gen_mul_q(TCGv rl,TCGv rh,TCGv arg1,TCGv arg2,uint32_t n,uint32_t up_shift)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
gen_mul_q_16(TCGv ret,TCGv arg1,TCGv arg2,uint32_t n)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
gen_mulr_q(TCGv ret,TCGv arg1,TCGv arg2,uint32_t n)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
gen_madds_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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, tcg_env, r1, temp64, r3);
2373 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2374 }
2375
2376 static inline void
gen_maddsi_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_maddsu_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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, tcg_env, r1, temp64, r3);
2391 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2392 }
2393
2394 static inline void
gen_maddsui_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_msubsi_32(TCGv ret,TCGv r1,TCGv r2,int32_t con)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, tcg_env, r1, r2, temp);
2406 }
2407
gen_msubsui_32(TCGv ret,TCGv r1,TCGv r2,int32_t con)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, tcg_env, r1, r2, temp);
2412 }
2413
2414 static inline void
gen_msubs_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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, tcg_env, r1, temp64, r3);
2421 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2422 }
2423
2424 static inline void
gen_msubsi_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_msubsu_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,TCGv r3)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, tcg_env, r1, temp64, r3);
2439 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2440 }
2441
2442 static inline void
gen_msubsui_64(TCGv ret_low,TCGv ret_high,TCGv r1,TCGv r2_low,TCGv r2_high,int32_t con)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
gen_saturate(TCGv ret,TCGv arg,int32_t up,int32_t low)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
gen_saturate_u(TCGv ret,TCGv arg,int32_t up)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
gen_shi(TCGv ret,TCGv r1,int32_t shift_count)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
gen_sh_hi(TCGv ret,TCGv r1,int32_t shiftcount)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
gen_shaci(TCGv ret,TCGv r1,int32_t shift_count)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
gen_shas(TCGv ret,TCGv r1,TCGv r2)2541 static void gen_shas(TCGv ret, TCGv r1, TCGv r2)
2542 {
2543 gen_helper_sha_ssov(ret, tcg_env, r1, r2);
2544 }
2545
gen_shasi(TCGv ret,TCGv r1,int32_t con)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
gen_sha_hi(TCGv ret,TCGv r1,int32_t shift_count)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)}; */
gen_sh_cond(int cond,TCGv ret,TCGv r1,TCGv 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
gen_sh_condi(int cond,TCGv ret,TCGv r1,int32_t con)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
gen_adds(TCGv ret,TCGv r1,TCGv r2)2594 static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
2595 {
2596 gen_helper_add_ssov(ret, tcg_env, r1, r2);
2597 }
2598
gen_addsi(TCGv ret,TCGv r1,int32_t con)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, tcg_env, r1, temp);
2603 }
2604
gen_addsui(TCGv ret,TCGv r1,int32_t con)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, tcg_env, r1, temp);
2609 }
2610
gen_subs(TCGv ret,TCGv r1,TCGv r2)2611 static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
2612 {
2613 gen_helper_sub_ssov(ret, tcg_env, r1, r2);
2614 }
2615
gen_subsu(TCGv ret,TCGv r1,TCGv r2)2616 static inline void gen_subsu(TCGv ret, TCGv r1, TCGv r2)
2617 {
2618 gen_helper_sub_suov(ret, tcg_env, r1, r2);
2619 }
2620
gen_bit_2op(TCGv ret,TCGv r1,TCGv r2,int pos1,int pos2,void (* op1)(TCGv,TCGv,TCGv),void (* op2)(TCGv,TCGv,TCGv))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]; */
gen_bit_1op(TCGv ret,TCGv r1,TCGv r2,int pos1,int pos2,void (* op1)(TCGv,TCGv,TCGv))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
gen_accumulating_cond(int cond,TCGv ret,TCGv r1,TCGv r2,void (* op)(TCGv,TCGv,TCGv))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
gen_accumulating_condi(int cond,TCGv ret,TCGv r1,int32_t con,void (* op)(TCGv,TCGv,TCGv))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
gen_eqany_bi(TCGv ret,TCGv r1,int32_t con)2681 static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
2682 {
2683 TCGv b0 = tcg_temp_new();
2684 TCGv b1 = tcg_temp_new();
2685 TCGv b2 = tcg_temp_new();
2686 TCGv b3 = tcg_temp_new();
2687
2688 /* byte 0 */
2689 tcg_gen_andi_tl(b0, r1, 0xff);
2690 tcg_gen_setcondi_tl(TCG_COND_EQ, b0, b0, con & 0xff);
2691
2692 /* byte 1 */
2693 tcg_gen_andi_tl(b1, r1, 0xff00);
2694 tcg_gen_setcondi_tl(TCG_COND_EQ, b1, b1, con & 0xff00);
2695
2696 /* byte 2 */
2697 tcg_gen_andi_tl(b2, r1, 0xff0000);
2698 tcg_gen_setcondi_tl(TCG_COND_EQ, b2, b2, con & 0xff0000);
2699
2700 /* byte 3 */
2701 tcg_gen_andi_tl(b3, r1, 0xff000000);
2702 tcg_gen_setcondi_tl(TCG_COND_EQ, b3, b3, con & 0xff000000);
2703
2704 /* combine them */
2705 tcg_gen_or_tl(ret, b0, b1);
2706 tcg_gen_or_tl(ret, ret, b2);
2707 tcg_gen_or_tl(ret, ret, b3);
2708 }
2709
gen_eqany_hi(TCGv ret,TCGv r1,int32_t con)2710 static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
2711 {
2712 TCGv h0 = tcg_temp_new();
2713 TCGv h1 = tcg_temp_new();
2714
2715 /* halfword 0 */
2716 tcg_gen_andi_tl(h0, r1, 0xffff);
2717 tcg_gen_setcondi_tl(TCG_COND_EQ, h0, h0, con & 0xffff);
2718
2719 /* halfword 1 */
2720 tcg_gen_andi_tl(h1, r1, 0xffff0000);
2721 tcg_gen_setcondi_tl(TCG_COND_EQ, h1, h1, con & 0xffff0000);
2722
2723 /* combine them */
2724 tcg_gen_or_tl(ret, h0, h1);
2725 }
2726
2727 /* mask = ((1 << width) -1) << pos;
2728 ret = (r1 & ~mask) | (r2 << pos) & mask); */
gen_insert(TCGv ret,TCGv r1,TCGv r2,TCGv width,TCGv pos)2729 static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
2730 {
2731 TCGv mask = tcg_temp_new();
2732 TCGv temp = tcg_temp_new();
2733 TCGv temp2 = tcg_temp_new();
2734
2735 tcg_gen_shl_tl(mask, tcg_constant_tl(1), width);
2736 tcg_gen_subi_tl(mask, mask, 1);
2737 tcg_gen_shl_tl(mask, mask, pos);
2738
2739 tcg_gen_shl_tl(temp, r2, pos);
2740 tcg_gen_and_tl(temp, temp, mask);
2741 tcg_gen_andc_tl(temp2, r1, mask);
2742 tcg_gen_or_tl(ret, temp, temp2);
2743 }
2744
gen_bsplit(TCGv rl,TCGv rh,TCGv r1)2745 static inline void gen_bsplit(TCGv rl, TCGv rh, TCGv r1)
2746 {
2747 TCGv_i64 temp = tcg_temp_new_i64();
2748
2749 gen_helper_bsplit(temp, r1);
2750 tcg_gen_extr_i64_i32(rl, rh, temp);
2751 }
2752
gen_unpack(TCGv rl,TCGv rh,TCGv r1)2753 static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1)
2754 {
2755 TCGv_i64 temp = tcg_temp_new_i64();
2756
2757 gen_helper_unpack(temp, r1);
2758 tcg_gen_extr_i64_i32(rl, rh, temp);
2759 }
2760
2761 static inline void
gen_dvinit_b(DisasContext * ctx,TCGv rl,TCGv rh,TCGv r1,TCGv r2)2762 gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
2763 {
2764 TCGv_i64 ret = tcg_temp_new_i64();
2765
2766 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
2767 gen_helper_dvinit_b_13(ret, tcg_env, r1, r2);
2768 } else {
2769 gen_helper_dvinit_b_131(ret, tcg_env, r1, r2);
2770 }
2771 tcg_gen_extr_i64_i32(rl, rh, ret);
2772 }
2773
2774 static inline void
gen_dvinit_h(DisasContext * ctx,TCGv rl,TCGv rh,TCGv r1,TCGv r2)2775 gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
2776 {
2777 TCGv_i64 ret = tcg_temp_new_i64();
2778
2779 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
2780 gen_helper_dvinit_h_13(ret, tcg_env, r1, r2);
2781 } else {
2782 gen_helper_dvinit_h_131(ret, tcg_env, r1, r2);
2783 }
2784 tcg_gen_extr_i64_i32(rl, rh, ret);
2785 }
2786
gen_calc_usb_mul_h(TCGv arg_low,TCGv arg_high)2787 static void gen_calc_usb_mul_h(TCGv arg_low, TCGv arg_high)
2788 {
2789 TCGv temp = tcg_temp_new();
2790 /* calc AV bit */
2791 tcg_gen_add_tl(temp, arg_low, arg_low);
2792 tcg_gen_xor_tl(temp, temp, arg_low);
2793 tcg_gen_add_tl(cpu_PSW_AV, arg_high, arg_high);
2794 tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, arg_high);
2795 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
2796 /* calc SAV bit */
2797 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2798 tcg_gen_movi_tl(cpu_PSW_V, 0);
2799 }
2800
gen_calc_usb_mulr_h(TCGv arg)2801 static void gen_calc_usb_mulr_h(TCGv arg)
2802 {
2803 TCGv temp = tcg_temp_new();
2804 /* calc AV bit */
2805 tcg_gen_add_tl(temp, arg, arg);
2806 tcg_gen_xor_tl(temp, temp, arg);
2807 tcg_gen_shli_tl(cpu_PSW_AV, temp, 16);
2808 tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
2809 /* calc SAV bit */
2810 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2811 /* clear V bit */
2812 tcg_gen_movi_tl(cpu_PSW_V, 0);
2813 }
2814
2815 /* helpers for generating program flow micro-ops */
2816
gen_save_pc(target_ulong pc)2817 static inline void gen_save_pc(target_ulong pc)
2818 {
2819 tcg_gen_movi_tl(cpu_PC, pc);
2820 }
2821
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)2822 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2823 {
2824 if (translator_use_goto_tb(&ctx->base, dest)) {
2825 tcg_gen_goto_tb(n);
2826 gen_save_pc(dest);
2827 tcg_gen_exit_tb(ctx->base.tb, n);
2828 } else {
2829 gen_save_pc(dest);
2830 tcg_gen_lookup_and_goto_ptr();
2831 }
2832 ctx->base.is_jmp = DISAS_NORETURN;
2833 }
2834
generate_trap(DisasContext * ctx,int class,int tin)2835 static void generate_trap(DisasContext *ctx, int class, int tin)
2836 {
2837 TCGv_i32 classtemp = tcg_constant_i32(class);
2838 TCGv_i32 tintemp = tcg_constant_i32(tin);
2839
2840 gen_save_pc(ctx->base.pc_next);
2841 gen_helper_raise_exception_sync(tcg_env, classtemp, tintemp);
2842 ctx->base.is_jmp = DISAS_NORETURN;
2843 }
2844
gen_branch_cond(DisasContext * ctx,TCGCond cond,TCGv r1,TCGv r2,int16_t address)2845 static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
2846 TCGv r2, int16_t address)
2847 {
2848 TCGLabel *jumpLabel = gen_new_label();
2849 tcg_gen_brcond_tl(cond, r1, r2, jumpLabel);
2850
2851 gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
2852
2853 gen_set_label(jumpLabel);
2854 gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2);
2855 }
2856
gen_branch_condi(DisasContext * ctx,TCGCond cond,TCGv r1,int r2,int16_t address)2857 static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1,
2858 int r2, int16_t address)
2859 {
2860 TCGv temp = tcg_constant_i32(r2);
2861 gen_branch_cond(ctx, cond, r1, temp, address);
2862 }
2863
gen_loop(DisasContext * ctx,int r1,int32_t offset)2864 static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
2865 {
2866 TCGLabel *l1 = gen_new_label();
2867
2868 tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
2869 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
2870 gen_goto_tb(ctx, 1, ctx->base.pc_next + offset);
2871 gen_set_label(l1);
2872 gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
2873 }
2874
gen_fcall_save_ctx(DisasContext * ctx)2875 static void gen_fcall_save_ctx(DisasContext *ctx)
2876 {
2877 TCGv temp = tcg_temp_new();
2878
2879 tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
2880 tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
2881 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
2882 tcg_gen_mov_tl(cpu_gpr_a[10], temp);
2883 }
2884
gen_fret(DisasContext * ctx)2885 static void gen_fret(DisasContext *ctx)
2886 {
2887 TCGv temp = tcg_temp_new();
2888
2889 tcg_gen_andi_tl(temp, cpu_gpr_a[11], ~0x1);
2890 tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
2891 tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
2892 tcg_gen_mov_tl(cpu_PC, temp);
2893 ctx->base.is_jmp = DISAS_EXIT;
2894 }
2895
gen_compute_branch(DisasContext * ctx,uint32_t opc,int r1,int r2,int32_t constant,int32_t offset)2896 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
2897 int r2 , int32_t constant , int32_t offset)
2898 {
2899 TCGv temp, temp2;
2900 int n;
2901
2902 switch (opc) {
2903 /* SB-format jumps */
2904 case OPC1_16_SB_J:
2905 case OPC1_32_B_J:
2906 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
2907 break;
2908 case OPC1_32_B_CALL:
2909 case OPC1_16_SB_CALL:
2910 gen_helper_1arg(call, ctx->pc_succ_insn);
2911 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
2912 break;
2913 case OPC1_16_SB_JZ:
2914 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
2915 break;
2916 case OPC1_16_SB_JNZ:
2917 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
2918 break;
2919 /* SBC-format jumps */
2920 case OPC1_16_SBC_JEQ:
2921 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
2922 break;
2923 case OPC1_16_SBC_JEQ2:
2924 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant,
2925 offset + 16);
2926 break;
2927 case OPC1_16_SBC_JNE:
2928 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
2929 break;
2930 case OPC1_16_SBC_JNE2:
2931 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15],
2932 constant, offset + 16);
2933 break;
2934 /* SBRN-format jumps */
2935 case OPC1_16_SBRN_JZ_T:
2936 temp = tcg_temp_new();
2937 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
2938 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
2939 break;
2940 case OPC1_16_SBRN_JNZ_T:
2941 temp = tcg_temp_new();
2942 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
2943 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
2944 break;
2945 /* SBR-format jumps */
2946 case OPC1_16_SBR_JEQ:
2947 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
2948 offset);
2949 break;
2950 case OPC1_16_SBR_JEQ2:
2951 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
2952 offset + 16);
2953 break;
2954 case OPC1_16_SBR_JNE:
2955 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
2956 offset);
2957 break;
2958 case OPC1_16_SBR_JNE2:
2959 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
2960 offset + 16);
2961 break;
2962 case OPC1_16_SBR_JNZ:
2963 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
2964 break;
2965 case OPC1_16_SBR_JNZ_A:
2966 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
2967 break;
2968 case OPC1_16_SBR_JGEZ:
2969 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
2970 break;
2971 case OPC1_16_SBR_JGTZ:
2972 gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
2973 break;
2974 case OPC1_16_SBR_JLEZ:
2975 gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
2976 break;
2977 case OPC1_16_SBR_JLTZ:
2978 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
2979 break;
2980 case OPC1_16_SBR_JZ:
2981 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
2982 break;
2983 case OPC1_16_SBR_JZ_A:
2984 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
2985 break;
2986 case OPC1_16_SBR_LOOP:
2987 gen_loop(ctx, r1, offset * 2 - 32);
2988 break;
2989 /* SR-format jumps */
2990 case OPC1_16_SR_JI:
2991 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
2992 ctx->base.is_jmp = DISAS_EXIT;
2993 break;
2994 case OPC2_32_SYS_RET:
2995 case OPC2_16_SR_RET:
2996 gen_helper_ret(tcg_env);
2997 ctx->base.is_jmp = DISAS_EXIT;
2998 break;
2999 /* B-format */
3000 case OPC1_32_B_CALLA:
3001 gen_helper_1arg(call, ctx->pc_succ_insn);
3002 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3003 break;
3004 case OPC1_32_B_FCALL:
3005 gen_fcall_save_ctx(ctx);
3006 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3007 break;
3008 case OPC1_32_B_FCALLA:
3009 gen_fcall_save_ctx(ctx);
3010 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3011 break;
3012 case OPC1_32_B_JLA:
3013 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3014 /* fall through */
3015 case OPC1_32_B_JA:
3016 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3017 break;
3018 case OPC1_32_B_JL:
3019 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3020 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3021 break;
3022 /* BOL format */
3023 case OPCM_32_BRC_EQ_NEQ:
3024 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
3025 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
3026 } else {
3027 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
3028 }
3029 break;
3030 case OPCM_32_BRC_GE:
3031 if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
3032 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
3033 } else {
3034 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3035 gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
3036 offset);
3037 }
3038 break;
3039 case OPCM_32_BRC_JLT:
3040 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
3041 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
3042 } else {
3043 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3044 gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
3045 offset);
3046 }
3047 break;
3048 case OPCM_32_BRC_JNE:
3049 temp = tcg_temp_new();
3050 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
3051 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3052 /* subi is unconditional */
3053 tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3054 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3055 } else {
3056 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3057 /* addi is unconditional */
3058 tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3059 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3060 }
3061 break;
3062 /* BRN format */
3063 case OPCM_32_BRN_JTT:
3064 n = MASK_OP_BRN_N(ctx->opcode);
3065
3066 temp = tcg_temp_new();
3067 tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << n));
3068
3069 if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
3070 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3071 } else {
3072 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3073 }
3074 break;
3075 /* BRR Format */
3076 case OPCM_32_BRR_EQ_NEQ:
3077 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
3078 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
3079 offset);
3080 } else {
3081 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3082 offset);
3083 }
3084 break;
3085 case OPCM_32_BRR_ADDR_EQ_NEQ:
3086 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
3087 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
3088 offset);
3089 } else {
3090 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
3091 offset);
3092 }
3093 break;
3094 case OPCM_32_BRR_GE:
3095 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
3096 gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3097 offset);
3098 } else {
3099 gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3100 offset);
3101 }
3102 break;
3103 case OPCM_32_BRR_JLT:
3104 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
3105 gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
3106 offset);
3107 } else {
3108 gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3109 offset);
3110 }
3111 break;
3112 case OPCM_32_BRR_LOOP:
3113 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
3114 gen_loop(ctx, r2, offset * 2);
3115 } else {
3116 /* OPC2_32_BRR_LOOPU */
3117 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3118 }
3119 break;
3120 case OPCM_32_BRR_JNE:
3121 temp = tcg_temp_new();
3122 temp2 = tcg_temp_new();
3123 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
3124 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3125 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3126 tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3127 /* subi is unconditional */
3128 tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3129 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3130 } else {
3131 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3132 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3133 tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3134 /* addi is unconditional */
3135 tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3136 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3137 }
3138 break;
3139 case OPCM_32_BRR_JNZ:
3140 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
3141 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3142 } else {
3143 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3144 }
3145 break;
3146 default:
3147 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3148 }
3149 }
3150
3151
3152 /*
3153 * Functions for decoding instructions
3154 */
3155
decode_src_opc(DisasContext * ctx,int op1)3156 static void decode_src_opc(DisasContext *ctx, int op1)
3157 {
3158 int r1;
3159 int32_t const4;
3160 TCGv temp, temp2;
3161
3162 r1 = MASK_OP_SRC_S1D(ctx->opcode);
3163 const4 = MASK_OP_SRC_CONST4_SEXT(ctx->opcode);
3164
3165 switch (op1) {
3166 case OPC1_16_SRC_ADD:
3167 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3168 break;
3169 case OPC1_16_SRC_ADD_A15:
3170 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[15], const4);
3171 break;
3172 case OPC1_16_SRC_ADD_15A:
3173 gen_addi_d(cpu_gpr_d[15], cpu_gpr_d[r1], const4);
3174 break;
3175 case OPC1_16_SRC_ADD_A:
3176 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], const4);
3177 break;
3178 case OPC1_16_SRC_CADD:
3179 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3180 cpu_gpr_d[15]);
3181 break;
3182 case OPC1_16_SRC_CADDN:
3183 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3184 cpu_gpr_d[15]);
3185 break;
3186 case OPC1_16_SRC_CMOV:
3187 temp = tcg_constant_tl(0);
3188 temp2 = tcg_constant_tl(const4);
3189 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3190 temp2, cpu_gpr_d[r1]);
3191 break;
3192 case OPC1_16_SRC_CMOVN:
3193 temp = tcg_constant_tl(0);
3194 temp2 = tcg_constant_tl(const4);
3195 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3196 temp2, cpu_gpr_d[r1]);
3197 break;
3198 case OPC1_16_SRC_EQ:
3199 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3200 const4);
3201 break;
3202 case OPC1_16_SRC_LT:
3203 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3204 const4);
3205 break;
3206 case OPC1_16_SRC_MOV:
3207 tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3208 break;
3209 case OPC1_16_SRC_MOV_A:
3210 const4 = MASK_OP_SRC_CONST4(ctx->opcode);
3211 tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
3212 break;
3213 case OPC1_16_SRC_MOV_E:
3214 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3215 CHECK_REG_PAIR(r1);
3216 tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3217 tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
3218 } else {
3219 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3220 }
3221 break;
3222 case OPC1_16_SRC_SH:
3223 gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3224 break;
3225 case OPC1_16_SRC_SHA:
3226 gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3227 break;
3228 default:
3229 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3230 }
3231 }
3232
decode_srr_opc(DisasContext * ctx,int op1)3233 static void decode_srr_opc(DisasContext *ctx, int op1)
3234 {
3235 int r1, r2;
3236 TCGv temp;
3237
3238 r1 = MASK_OP_SRR_S1D(ctx->opcode);
3239 r2 = MASK_OP_SRR_S2(ctx->opcode);
3240
3241 switch (op1) {
3242 case OPC1_16_SRR_ADD:
3243 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3244 break;
3245 case OPC1_16_SRR_ADD_A15:
3246 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3247 break;
3248 case OPC1_16_SRR_ADD_15A:
3249 gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3250 break;
3251 case OPC1_16_SRR_ADD_A:
3252 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
3253 break;
3254 case OPC1_16_SRR_ADDS:
3255 gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3256 break;
3257 case OPC1_16_SRR_AND:
3258 tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3259 break;
3260 case OPC1_16_SRR_CMOV:
3261 temp = tcg_constant_tl(0);
3262 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3263 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3264 break;
3265 case OPC1_16_SRR_CMOVN:
3266 temp = tcg_constant_tl(0);
3267 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3268 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3269 break;
3270 case OPC1_16_SRR_EQ:
3271 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3272 cpu_gpr_d[r2]);
3273 break;
3274 case OPC1_16_SRR_LT:
3275 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3276 cpu_gpr_d[r2]);
3277 break;
3278 case OPC1_16_SRR_MOV:
3279 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]);
3280 break;
3281 case OPC1_16_SRR_MOV_A:
3282 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]);
3283 break;
3284 case OPC1_16_SRR_MOV_AA:
3285 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_a[r2]);
3286 break;
3287 case OPC1_16_SRR_MOV_D:
3288 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]);
3289 break;
3290 case OPC1_16_SRR_MUL:
3291 gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3292 break;
3293 case OPC1_16_SRR_OR:
3294 tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3295 break;
3296 case OPC1_16_SRR_SUB:
3297 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3298 break;
3299 case OPC1_16_SRR_SUB_A15B:
3300 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3301 break;
3302 case OPC1_16_SRR_SUB_15AB:
3303 gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3304 break;
3305 case OPC1_16_SRR_SUBS:
3306 gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3307 break;
3308 case OPC1_16_SRR_XOR:
3309 tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3310 break;
3311 default:
3312 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3313 }
3314 }
3315
decode_ssr_opc(DisasContext * ctx,int op1)3316 static void decode_ssr_opc(DisasContext *ctx, int op1)
3317 {
3318 int r1, r2;
3319
3320 r1 = MASK_OP_SSR_S1(ctx->opcode);
3321 r2 = MASK_OP_SSR_S2(ctx->opcode);
3322
3323 switch (op1) {
3324 case OPC1_16_SSR_ST_A:
3325 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3326 break;
3327 case OPC1_16_SSR_ST_A_POSTINC:
3328 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3329 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3330 break;
3331 case OPC1_16_SSR_ST_B:
3332 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3333 break;
3334 case OPC1_16_SSR_ST_B_POSTINC:
3335 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3336 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3337 break;
3338 case OPC1_16_SSR_ST_H:
3339 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3340 break;
3341 case OPC1_16_SSR_ST_H_POSTINC:
3342 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3343 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3344 break;
3345 case OPC1_16_SSR_ST_W:
3346 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3347 break;
3348 case OPC1_16_SSR_ST_W_POSTINC:
3349 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3350 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3351 break;
3352 default:
3353 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3354 }
3355 }
3356
decode_sc_opc(DisasContext * ctx,int op1)3357 static void decode_sc_opc(DisasContext *ctx, int op1)
3358 {
3359 int32_t const16;
3360
3361 const16 = MASK_OP_SC_CONST8(ctx->opcode);
3362
3363 switch (op1) {
3364 case OPC1_16_SC_AND:
3365 tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3366 break;
3367 case OPC1_16_SC_BISR:
3368 if (ctx->priv == TRICORE_PRIV_SM) {
3369 gen_helper_1arg(bisr, const16 & 0xff);
3370 } else {
3371 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
3372 }
3373 break;
3374 case OPC1_16_SC_LD_A:
3375 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3376 break;
3377 case OPC1_16_SC_LD_W:
3378 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3379 break;
3380 case OPC1_16_SC_MOV:
3381 tcg_gen_movi_tl(cpu_gpr_d[15], const16);
3382 break;
3383 case OPC1_16_SC_OR:
3384 tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3385 break;
3386 case OPC1_16_SC_ST_A:
3387 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3388 break;
3389 case OPC1_16_SC_ST_W:
3390 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3391 break;
3392 case OPC1_16_SC_SUB_A:
3393 tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
3394 break;
3395 default:
3396 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3397 }
3398 }
3399
decode_slr_opc(DisasContext * ctx,int op1)3400 static void decode_slr_opc(DisasContext *ctx, int op1)
3401 {
3402 int r1, r2;
3403
3404 r1 = MASK_OP_SLR_D(ctx->opcode);
3405 r2 = MASK_OP_SLR_S2(ctx->opcode);
3406
3407 switch (op1) {
3408 /* SLR-format */
3409 case OPC1_16_SLR_LD_A:
3410 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3411 break;
3412 case OPC1_16_SLR_LD_A_POSTINC:
3413 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3414 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3415 break;
3416 case OPC1_16_SLR_LD_BU:
3417 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3418 break;
3419 case OPC1_16_SLR_LD_BU_POSTINC:
3420 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3421 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3422 break;
3423 case OPC1_16_SLR_LD_H:
3424 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3425 break;
3426 case OPC1_16_SLR_LD_H_POSTINC:
3427 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3428 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3429 break;
3430 case OPC1_16_SLR_LD_W:
3431 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3432 break;
3433 case OPC1_16_SLR_LD_W_POSTINC:
3434 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3435 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3436 break;
3437 default:
3438 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3439 }
3440 }
3441
decode_sro_opc(DisasContext * ctx,int op1)3442 static void decode_sro_opc(DisasContext *ctx, int op1)
3443 {
3444 int r2;
3445 int32_t address;
3446
3447 r2 = MASK_OP_SRO_S2(ctx->opcode);
3448 address = MASK_OP_SRO_OFF4(ctx->opcode);
3449
3450 /* SRO-format */
3451 switch (op1) {
3452 case OPC1_16_SRO_LD_A:
3453 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3454 break;
3455 case OPC1_16_SRO_LD_BU:
3456 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3457 break;
3458 case OPC1_16_SRO_LD_H:
3459 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3460 break;
3461 case OPC1_16_SRO_LD_W:
3462 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3463 break;
3464 case OPC1_16_SRO_ST_A:
3465 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3466 break;
3467 case OPC1_16_SRO_ST_B:
3468 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3469 break;
3470 case OPC1_16_SRO_ST_H:
3471 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3472 break;
3473 case OPC1_16_SRO_ST_W:
3474 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3475 break;
3476 default:
3477 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3478 }
3479 }
3480
decode_sr_system(DisasContext * ctx)3481 static void decode_sr_system(DisasContext *ctx)
3482 {
3483 uint32_t op2;
3484 op2 = MASK_OP_SR_OP2(ctx->opcode);
3485
3486 switch (op2) {
3487 case OPC2_16_SR_NOP:
3488 break;
3489 case OPC2_16_SR_RET:
3490 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
3491 break;
3492 case OPC2_16_SR_RFE:
3493 gen_helper_rfe(tcg_env);
3494 ctx->base.is_jmp = DISAS_EXIT;
3495 break;
3496 case OPC2_16_SR_DEBUG:
3497 /* raise EXCP_DEBUG */
3498 break;
3499 case OPC2_16_SR_FRET:
3500 gen_fret(ctx);
3501 break;
3502 default:
3503 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3504 }
3505 }
3506
decode_sr_accu(DisasContext * ctx)3507 static void decode_sr_accu(DisasContext *ctx)
3508 {
3509 uint32_t op2;
3510 uint32_t r1;
3511
3512 r1 = MASK_OP_SR_S1D(ctx->opcode);
3513 op2 = MASK_OP_SR_OP2(ctx->opcode);
3514
3515 switch (op2) {
3516 case OPC2_16_SR_RSUB:
3517 /* calc V bit -- overflow only if r1 = -0x80000000 */
3518 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r1], -0x80000000);
3519 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
3520 /* calc SV bit */
3521 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
3522 /* sub */
3523 tcg_gen_neg_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3524 /* calc av */
3525 tcg_gen_add_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_gpr_d[r1]);
3526 tcg_gen_xor_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_PSW_AV);
3527 /* calc sav */
3528 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3529 break;
3530 case OPC2_16_SR_SAT_B:
3531 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
3532 break;
3533 case OPC2_16_SR_SAT_BU:
3534 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
3535 break;
3536 case OPC2_16_SR_SAT_H:
3537 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
3538 break;
3539 case OPC2_16_SR_SAT_HU:
3540 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
3541 break;
3542 default:
3543 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3544 }
3545 }
3546
decode_16Bit_opc(DisasContext * ctx)3547 static void decode_16Bit_opc(DisasContext *ctx)
3548 {
3549 int op1;
3550 int r1, r2;
3551 int32_t const16;
3552 int32_t address;
3553 TCGv temp;
3554
3555 op1 = MASK_OP_MAJOR(ctx->opcode);
3556
3557 /* handle ADDSC.A opcode only being 6 bit long */
3558 if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
3559 op1 = OPC1_16_SRRS_ADDSC_A;
3560 }
3561
3562 switch (op1) {
3563 case OPC1_16_SRC_ADD:
3564 case OPC1_16_SRC_ADD_A15:
3565 case OPC1_16_SRC_ADD_15A:
3566 case OPC1_16_SRC_ADD_A:
3567 case OPC1_16_SRC_CADD:
3568 case OPC1_16_SRC_CADDN:
3569 case OPC1_16_SRC_CMOV:
3570 case OPC1_16_SRC_CMOVN:
3571 case OPC1_16_SRC_EQ:
3572 case OPC1_16_SRC_LT:
3573 case OPC1_16_SRC_MOV:
3574 case OPC1_16_SRC_MOV_A:
3575 case OPC1_16_SRC_MOV_E:
3576 case OPC1_16_SRC_SH:
3577 case OPC1_16_SRC_SHA:
3578 decode_src_opc(ctx, op1);
3579 break;
3580 /* SRR-format */
3581 case OPC1_16_SRR_ADD:
3582 case OPC1_16_SRR_ADD_A15:
3583 case OPC1_16_SRR_ADD_15A:
3584 case OPC1_16_SRR_ADD_A:
3585 case OPC1_16_SRR_ADDS:
3586 case OPC1_16_SRR_AND:
3587 case OPC1_16_SRR_CMOV:
3588 case OPC1_16_SRR_CMOVN:
3589 case OPC1_16_SRR_EQ:
3590 case OPC1_16_SRR_LT:
3591 case OPC1_16_SRR_MOV:
3592 case OPC1_16_SRR_MOV_A:
3593 case OPC1_16_SRR_MOV_AA:
3594 case OPC1_16_SRR_MOV_D:
3595 case OPC1_16_SRR_MUL:
3596 case OPC1_16_SRR_OR:
3597 case OPC1_16_SRR_SUB:
3598 case OPC1_16_SRR_SUB_A15B:
3599 case OPC1_16_SRR_SUB_15AB:
3600 case OPC1_16_SRR_SUBS:
3601 case OPC1_16_SRR_XOR:
3602 decode_srr_opc(ctx, op1);
3603 break;
3604 /* SSR-format */
3605 case OPC1_16_SSR_ST_A:
3606 case OPC1_16_SSR_ST_A_POSTINC:
3607 case OPC1_16_SSR_ST_B:
3608 case OPC1_16_SSR_ST_B_POSTINC:
3609 case OPC1_16_SSR_ST_H:
3610 case OPC1_16_SSR_ST_H_POSTINC:
3611 case OPC1_16_SSR_ST_W:
3612 case OPC1_16_SSR_ST_W_POSTINC:
3613 decode_ssr_opc(ctx, op1);
3614 break;
3615 /* SRRS-format */
3616 case OPC1_16_SRRS_ADDSC_A:
3617 r2 = MASK_OP_SRRS_S2(ctx->opcode);
3618 r1 = MASK_OP_SRRS_S1D(ctx->opcode);
3619 const16 = MASK_OP_SRRS_N(ctx->opcode);
3620 temp = tcg_temp_new();
3621 tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
3622 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
3623 break;
3624 /* SLRO-format */
3625 case OPC1_16_SLRO_LD_A:
3626 r1 = MASK_OP_SLRO_D(ctx->opcode);
3627 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3628 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3629 break;
3630 case OPC1_16_SLRO_LD_BU:
3631 r1 = MASK_OP_SLRO_D(ctx->opcode);
3632 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3633 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
3634 break;
3635 case OPC1_16_SLRO_LD_H:
3636 r1 = MASK_OP_SLRO_D(ctx->opcode);
3637 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3638 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
3639 break;
3640 case OPC1_16_SLRO_LD_W:
3641 r1 = MASK_OP_SLRO_D(ctx->opcode);
3642 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3643 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3644 break;
3645 /* SB-format */
3646 case OPC1_16_SB_CALL:
3647 case OPC1_16_SB_J:
3648 case OPC1_16_SB_JNZ:
3649 case OPC1_16_SB_JZ:
3650 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
3651 gen_compute_branch(ctx, op1, 0, 0, 0, address);
3652 break;
3653 /* SBC-format */
3654 case OPC1_16_SBC_JEQ:
3655 case OPC1_16_SBC_JNE:
3656 address = MASK_OP_SBC_DISP4(ctx->opcode);
3657 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
3658 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3659 break;
3660 case OPC1_16_SBC_JEQ2:
3661 case OPC1_16_SBC_JNE2:
3662 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3663 address = MASK_OP_SBC_DISP4(ctx->opcode);
3664 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
3665 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3666 } else {
3667 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3668 }
3669 break;
3670 /* SBRN-format */
3671 case OPC1_16_SBRN_JNZ_T:
3672 case OPC1_16_SBRN_JZ_T:
3673 address = MASK_OP_SBRN_DISP4(ctx->opcode);
3674 const16 = MASK_OP_SBRN_N(ctx->opcode);
3675 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3676 break;
3677 /* SBR-format */
3678 case OPC1_16_SBR_JEQ2:
3679 case OPC1_16_SBR_JNE2:
3680 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3681 r1 = MASK_OP_SBR_S2(ctx->opcode);
3682 address = MASK_OP_SBR_DISP4(ctx->opcode);
3683 gen_compute_branch(ctx, op1, r1, 0, 0, address);
3684 } else {
3685 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3686 }
3687 break;
3688 case OPC1_16_SBR_JEQ:
3689 case OPC1_16_SBR_JGEZ:
3690 case OPC1_16_SBR_JGTZ:
3691 case OPC1_16_SBR_JLEZ:
3692 case OPC1_16_SBR_JLTZ:
3693 case OPC1_16_SBR_JNE:
3694 case OPC1_16_SBR_JNZ:
3695 case OPC1_16_SBR_JNZ_A:
3696 case OPC1_16_SBR_JZ:
3697 case OPC1_16_SBR_JZ_A:
3698 case OPC1_16_SBR_LOOP:
3699 r1 = MASK_OP_SBR_S2(ctx->opcode);
3700 address = MASK_OP_SBR_DISP4(ctx->opcode);
3701 gen_compute_branch(ctx, op1, r1, 0, 0, address);
3702 break;
3703 /* SC-format */
3704 case OPC1_16_SC_AND:
3705 case OPC1_16_SC_BISR:
3706 case OPC1_16_SC_LD_A:
3707 case OPC1_16_SC_LD_W:
3708 case OPC1_16_SC_MOV:
3709 case OPC1_16_SC_OR:
3710 case OPC1_16_SC_ST_A:
3711 case OPC1_16_SC_ST_W:
3712 case OPC1_16_SC_SUB_A:
3713 decode_sc_opc(ctx, op1);
3714 break;
3715 /* SLR-format */
3716 case OPC1_16_SLR_LD_A:
3717 case OPC1_16_SLR_LD_A_POSTINC:
3718 case OPC1_16_SLR_LD_BU:
3719 case OPC1_16_SLR_LD_BU_POSTINC:
3720 case OPC1_16_SLR_LD_H:
3721 case OPC1_16_SLR_LD_H_POSTINC:
3722 case OPC1_16_SLR_LD_W:
3723 case OPC1_16_SLR_LD_W_POSTINC:
3724 decode_slr_opc(ctx, op1);
3725 break;
3726 /* SRO-format */
3727 case OPC1_16_SRO_LD_A:
3728 case OPC1_16_SRO_LD_BU:
3729 case OPC1_16_SRO_LD_H:
3730 case OPC1_16_SRO_LD_W:
3731 case OPC1_16_SRO_ST_A:
3732 case OPC1_16_SRO_ST_B:
3733 case OPC1_16_SRO_ST_H:
3734 case OPC1_16_SRO_ST_W:
3735 decode_sro_opc(ctx, op1);
3736 break;
3737 /* SSRO-format */
3738 case OPC1_16_SSRO_ST_A:
3739 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3740 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3741 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3742 break;
3743 case OPC1_16_SSRO_ST_B:
3744 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3745 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3746 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
3747 break;
3748 case OPC1_16_SSRO_ST_H:
3749 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3750 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3751 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
3752 break;
3753 case OPC1_16_SSRO_ST_W:
3754 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3755 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3756 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3757 break;
3758 /* SR-format */
3759 case OPCM_16_SR_SYSTEM:
3760 decode_sr_system(ctx);
3761 break;
3762 case OPCM_16_SR_ACCU:
3763 decode_sr_accu(ctx);
3764 break;
3765 case OPC1_16_SR_JI:
3766 r1 = MASK_OP_SR_S1D(ctx->opcode);
3767 gen_compute_branch(ctx, op1, r1, 0, 0, 0);
3768 break;
3769 case OPC1_16_SR_NOT:
3770 r1 = MASK_OP_SR_S1D(ctx->opcode);
3771 tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3772 break;
3773 default:
3774 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3775 }
3776 }
3777
3778 /*
3779 * 32 bit instructions
3780 */
3781
3782 /* ABS-format */
decode_abs_ldw(DisasContext * ctx)3783 static void decode_abs_ldw(DisasContext *ctx)
3784 {
3785 int32_t op2;
3786 int32_t r1;
3787 uint32_t address;
3788 TCGv temp;
3789
3790 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3791 address = MASK_OP_ABS_OFF18(ctx->opcode);
3792 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3793
3794 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3795
3796 switch (op2) {
3797 case OPC2_32_ABS_LD_A:
3798 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
3799 break;
3800 case OPC2_32_ABS_LD_D:
3801 CHECK_REG_PAIR(r1);
3802 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
3803 break;
3804 case OPC2_32_ABS_LD_DA:
3805 CHECK_REG_PAIR(r1);
3806 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
3807 break;
3808 case OPC2_32_ABS_LD_W:
3809 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
3810 break;
3811 default:
3812 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3813 }
3814 }
3815
decode_abs_ldb(DisasContext * ctx)3816 static void decode_abs_ldb(DisasContext *ctx)
3817 {
3818 int32_t op2;
3819 int32_t r1;
3820 uint32_t address;
3821 TCGv temp;
3822
3823 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3824 address = MASK_OP_ABS_OFF18(ctx->opcode);
3825 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3826
3827 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3828
3829 switch (op2) {
3830 case OPC2_32_ABS_LD_B:
3831 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB);
3832 break;
3833 case OPC2_32_ABS_LD_BU:
3834 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
3835 break;
3836 case OPC2_32_ABS_LD_H:
3837 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW);
3838 break;
3839 case OPC2_32_ABS_LD_HU:
3840 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
3841 break;
3842 default:
3843 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3844 }
3845 }
3846
decode_abs_ldst_swap(DisasContext * ctx)3847 static void decode_abs_ldst_swap(DisasContext *ctx)
3848 {
3849 int32_t op2;
3850 int32_t r1;
3851 uint32_t address;
3852 TCGv temp;
3853
3854 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3855 address = MASK_OP_ABS_OFF18(ctx->opcode);
3856 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3857
3858 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3859
3860 switch (op2) {
3861 case OPC2_32_ABS_LDMST:
3862 gen_ldmst(ctx, r1, temp);
3863 break;
3864 case OPC2_32_ABS_SWAP_W:
3865 gen_swap(ctx, r1, temp);
3866 break;
3867 default:
3868 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3869 }
3870 }
3871
decode_abs_ldst_context(DisasContext * ctx)3872 static void decode_abs_ldst_context(DisasContext *ctx)
3873 {
3874 uint32_t op2;
3875 int32_t off18;
3876
3877 off18 = MASK_OP_ABS_OFF18(ctx->opcode);
3878 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3879
3880 switch (op2) {
3881 case OPC2_32_ABS_LDLCX:
3882 gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18));
3883 break;
3884 case OPC2_32_ABS_LDUCX:
3885 gen_helper_1arg(lducx, EA_ABS_FORMAT(off18));
3886 break;
3887 case OPC2_32_ABS_STLCX:
3888 gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18));
3889 break;
3890 case OPC2_32_ABS_STUCX:
3891 gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
3892 break;
3893 default:
3894 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3895 }
3896 }
3897
decode_abs_store(DisasContext * ctx)3898 static void decode_abs_store(DisasContext *ctx)
3899 {
3900 int32_t op2;
3901 int32_t r1;
3902 uint32_t address;
3903 TCGv temp;
3904
3905 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3906 address = MASK_OP_ABS_OFF18(ctx->opcode);
3907 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3908
3909 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3910
3911 switch (op2) {
3912 case OPC2_32_ABS_ST_A:
3913 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
3914 break;
3915 case OPC2_32_ABS_ST_D:
3916 CHECK_REG_PAIR(r1);
3917 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
3918 break;
3919 case OPC2_32_ABS_ST_DA:
3920 CHECK_REG_PAIR(r1);
3921 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
3922 break;
3923 case OPC2_32_ABS_ST_W:
3924 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
3925 break;
3926 default:
3927 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3928 }
3929 }
3930
decode_abs_storeb_h(DisasContext * ctx)3931 static void decode_abs_storeb_h(DisasContext *ctx)
3932 {
3933 int32_t op2;
3934 int32_t r1;
3935 uint32_t address;
3936 TCGv temp;
3937
3938 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3939 address = MASK_OP_ABS_OFF18(ctx->opcode);
3940 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3941
3942 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3943
3944 switch (op2) {
3945 case OPC2_32_ABS_ST_B:
3946 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
3947 break;
3948 case OPC2_32_ABS_ST_H:
3949 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
3950 break;
3951 default:
3952 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3953 }
3954 }
3955
3956 /* Bit-format */
3957
decode_bit_andacc(DisasContext * ctx)3958 static void decode_bit_andacc(DisasContext *ctx)
3959 {
3960 uint32_t op2;
3961 int r1, r2, r3;
3962 int pos1, pos2;
3963
3964 r1 = MASK_OP_BIT_S1(ctx->opcode);
3965 r2 = MASK_OP_BIT_S2(ctx->opcode);
3966 r3 = MASK_OP_BIT_D(ctx->opcode);
3967 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
3968 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
3969 op2 = MASK_OP_BIT_OP2(ctx->opcode);
3970
3971
3972 switch (op2) {
3973 case OPC2_32_BIT_AND_AND_T:
3974 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
3975 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
3976 break;
3977 case OPC2_32_BIT_AND_ANDN_T:
3978 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
3979 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
3980 break;
3981 case OPC2_32_BIT_AND_NOR_T:
3982 if (TCG_TARGET_HAS_andc_i32) {
3983 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
3984 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
3985 } else {
3986 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
3987 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
3988 }
3989 break;
3990 case OPC2_32_BIT_AND_OR_T:
3991 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
3992 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
3993 break;
3994 default:
3995 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3996 }
3997 }
3998
decode_bit_logical_t(DisasContext * ctx)3999 static void decode_bit_logical_t(DisasContext *ctx)
4000 {
4001 uint32_t op2;
4002 int r1, r2, r3;
4003 int pos1, pos2;
4004 r1 = MASK_OP_BIT_S1(ctx->opcode);
4005 r2 = MASK_OP_BIT_S2(ctx->opcode);
4006 r3 = MASK_OP_BIT_D(ctx->opcode);
4007 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4008 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4009 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4010
4011 switch (op2) {
4012 case OPC2_32_BIT_AND_T:
4013 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4014 pos1, pos2, &tcg_gen_and_tl);
4015 break;
4016 case OPC2_32_BIT_ANDN_T:
4017 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4018 pos1, pos2, &tcg_gen_andc_tl);
4019 break;
4020 case OPC2_32_BIT_NOR_T:
4021 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4022 pos1, pos2, &tcg_gen_nor_tl);
4023 break;
4024 case OPC2_32_BIT_OR_T:
4025 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4026 pos1, pos2, &tcg_gen_or_tl);
4027 break;
4028 default:
4029 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4030 }
4031 }
4032
decode_bit_insert(DisasContext * ctx)4033 static void decode_bit_insert(DisasContext *ctx)
4034 {
4035 uint32_t op2;
4036 int r1, r2, r3;
4037 int pos1, pos2;
4038 TCGv temp;
4039 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4040 r1 = MASK_OP_BIT_S1(ctx->opcode);
4041 r2 = MASK_OP_BIT_S2(ctx->opcode);
4042 r3 = MASK_OP_BIT_D(ctx->opcode);
4043 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4044 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4045
4046 temp = tcg_temp_new();
4047
4048 tcg_gen_shri_tl(temp, cpu_gpr_d[r2], pos2);
4049 if (op2 == OPC2_32_BIT_INSN_T) {
4050 tcg_gen_not_tl(temp, temp);
4051 }
4052 tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, pos1, 1);
4053 }
4054
decode_bit_logical_t2(DisasContext * ctx)4055 static void decode_bit_logical_t2(DisasContext *ctx)
4056 {
4057 uint32_t op2;
4058
4059 int r1, r2, r3;
4060 int pos1, pos2;
4061
4062 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4063 r1 = MASK_OP_BIT_S1(ctx->opcode);
4064 r2 = MASK_OP_BIT_S2(ctx->opcode);
4065 r3 = MASK_OP_BIT_D(ctx->opcode);
4066 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4067 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4068
4069 switch (op2) {
4070 case OPC2_32_BIT_NAND_T:
4071 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4072 pos1, pos2, &tcg_gen_nand_tl);
4073 break;
4074 case OPC2_32_BIT_ORN_T:
4075 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4076 pos1, pos2, &tcg_gen_orc_tl);
4077 break;
4078 case OPC2_32_BIT_XNOR_T:
4079 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4080 pos1, pos2, &tcg_gen_eqv_tl);
4081 break;
4082 case OPC2_32_BIT_XOR_T:
4083 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4084 pos1, pos2, &tcg_gen_xor_tl);
4085 break;
4086 default:
4087 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4088 }
4089 }
4090
decode_bit_orand(DisasContext * ctx)4091 static void decode_bit_orand(DisasContext *ctx)
4092 {
4093 uint32_t op2;
4094
4095 int r1, r2, r3;
4096 int pos1, pos2;
4097
4098 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4099 r1 = MASK_OP_BIT_S1(ctx->opcode);
4100 r2 = MASK_OP_BIT_S2(ctx->opcode);
4101 r3 = MASK_OP_BIT_D(ctx->opcode);
4102 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4103 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4104
4105 switch (op2) {
4106 case OPC2_32_BIT_OR_AND_T:
4107 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4108 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl);
4109 break;
4110 case OPC2_32_BIT_OR_ANDN_T:
4111 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4112 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
4113 break;
4114 case OPC2_32_BIT_OR_NOR_T:
4115 if (TCG_TARGET_HAS_orc_i32) {
4116 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4117 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
4118 } else {
4119 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4120 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_or_tl);
4121 }
4122 break;
4123 case OPC2_32_BIT_OR_OR_T:
4124 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4125 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
4126 break;
4127 default:
4128 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4129 }
4130 }
4131
decode_bit_sh_logic1(DisasContext * ctx)4132 static void decode_bit_sh_logic1(DisasContext *ctx)
4133 {
4134 uint32_t op2;
4135 int r1, r2, r3;
4136 int pos1, pos2;
4137 TCGv temp;
4138
4139 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4140 r1 = MASK_OP_BIT_S1(ctx->opcode);
4141 r2 = MASK_OP_BIT_S2(ctx->opcode);
4142 r3 = MASK_OP_BIT_D(ctx->opcode);
4143 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4144 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4145
4146 temp = tcg_temp_new();
4147
4148 switch (op2) {
4149 case OPC2_32_BIT_SH_AND_T:
4150 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4151 pos1, pos2, &tcg_gen_and_tl);
4152 break;
4153 case OPC2_32_BIT_SH_ANDN_T:
4154 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4155 pos1, pos2, &tcg_gen_andc_tl);
4156 break;
4157 case OPC2_32_BIT_SH_NOR_T:
4158 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4159 pos1, pos2, &tcg_gen_nor_tl);
4160 break;
4161 case OPC2_32_BIT_SH_OR_T:
4162 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4163 pos1, pos2, &tcg_gen_or_tl);
4164 break;
4165 default:
4166 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4167 }
4168 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4169 tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4170 }
4171
decode_bit_sh_logic2(DisasContext * ctx)4172 static void decode_bit_sh_logic2(DisasContext *ctx)
4173 {
4174 uint32_t op2;
4175 int r1, r2, r3;
4176 int pos1, pos2;
4177 TCGv temp;
4178
4179 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4180 r1 = MASK_OP_BIT_S1(ctx->opcode);
4181 r2 = MASK_OP_BIT_S2(ctx->opcode);
4182 r3 = MASK_OP_BIT_D(ctx->opcode);
4183 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4184 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4185
4186 temp = tcg_temp_new();
4187
4188 switch (op2) {
4189 case OPC2_32_BIT_SH_NAND_T:
4190 gen_bit_1op(temp, cpu_gpr_d[r1] , cpu_gpr_d[r2] ,
4191 pos1, pos2, &tcg_gen_nand_tl);
4192 break;
4193 case OPC2_32_BIT_SH_ORN_T:
4194 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4195 pos1, pos2, &tcg_gen_orc_tl);
4196 break;
4197 case OPC2_32_BIT_SH_XNOR_T:
4198 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4199 pos1, pos2, &tcg_gen_eqv_tl);
4200 break;
4201 case OPC2_32_BIT_SH_XOR_T:
4202 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4203 pos1, pos2, &tcg_gen_xor_tl);
4204 break;
4205 default:
4206 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4207 }
4208 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4209 tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4210 }
4211
4212 /* BO-format */
4213
4214
decode_bo_addrmode_post_pre_base(DisasContext * ctx)4215 static void decode_bo_addrmode_post_pre_base(DisasContext *ctx)
4216 {
4217 uint32_t op2;
4218 uint32_t off10;
4219 int32_t r1, r2;
4220 TCGv temp;
4221
4222 r1 = MASK_OP_BO_S1D(ctx->opcode);
4223 r2 = MASK_OP_BO_S2(ctx->opcode);
4224 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4225 op2 = MASK_OP_BO_OP2(ctx->opcode);
4226
4227 switch (op2) {
4228 case OPC2_32_BO_CACHEA_WI_SHORTOFF:
4229 case OPC2_32_BO_CACHEA_W_SHORTOFF:
4230 case OPC2_32_BO_CACHEA_I_SHORTOFF:
4231 /* instruction to access the cache */
4232 break;
4233 case OPC2_32_BO_CACHEA_WI_POSTINC:
4234 case OPC2_32_BO_CACHEA_W_POSTINC:
4235 case OPC2_32_BO_CACHEA_I_POSTINC:
4236 /* instruction to access the cache, but we still need to handle
4237 the addressing mode */
4238 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4239 break;
4240 case OPC2_32_BO_CACHEA_WI_PREINC:
4241 case OPC2_32_BO_CACHEA_W_PREINC:
4242 case OPC2_32_BO_CACHEA_I_PREINC:
4243 /* instruction to access the cache, but we still need to handle
4244 the addressing mode */
4245 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4246 break;
4247 case OPC2_32_BO_CACHEI_WI_SHORTOFF:
4248 case OPC2_32_BO_CACHEI_W_SHORTOFF:
4249 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
4250 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4251 }
4252 break;
4253 case OPC2_32_BO_CACHEI_W_POSTINC:
4254 case OPC2_32_BO_CACHEI_WI_POSTINC:
4255 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4256 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4257 } else {
4258 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4259 }
4260 break;
4261 case OPC2_32_BO_CACHEI_W_PREINC:
4262 case OPC2_32_BO_CACHEI_WI_PREINC:
4263 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4264 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4265 } else {
4266 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4267 }
4268 break;
4269 case OPC2_32_BO_ST_A_SHORTOFF:
4270 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4271 break;
4272 case OPC2_32_BO_ST_A_POSTINC:
4273 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4274 MO_LESL);
4275 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4276 break;
4277 case OPC2_32_BO_ST_A_PREINC:
4278 gen_st_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4279 break;
4280 case OPC2_32_BO_ST_B_SHORTOFF:
4281 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4282 break;
4283 case OPC2_32_BO_ST_B_POSTINC:
4284 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4285 MO_UB);
4286 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4287 break;
4288 case OPC2_32_BO_ST_B_PREINC:
4289 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4290 break;
4291 case OPC2_32_BO_ST_D_SHORTOFF:
4292 CHECK_REG_PAIR(r1);
4293 gen_offset_st_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4294 off10, ctx);
4295 break;
4296 case OPC2_32_BO_ST_D_POSTINC:
4297 CHECK_REG_PAIR(r1);
4298 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
4299 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4300 break;
4301 case OPC2_32_BO_ST_D_PREINC:
4302 CHECK_REG_PAIR(r1);
4303 temp = tcg_temp_new();
4304 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4305 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4306 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4307 break;
4308 case OPC2_32_BO_ST_DA_SHORTOFF:
4309 CHECK_REG_PAIR(r1);
4310 gen_offset_st_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4311 off10, ctx);
4312 break;
4313 case OPC2_32_BO_ST_DA_POSTINC:
4314 CHECK_REG_PAIR(r1);
4315 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
4316 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4317 break;
4318 case OPC2_32_BO_ST_DA_PREINC:
4319 CHECK_REG_PAIR(r1);
4320 temp = tcg_temp_new();
4321 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4322 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4323 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4324 break;
4325 case OPC2_32_BO_ST_H_SHORTOFF:
4326 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4327 break;
4328 case OPC2_32_BO_ST_H_POSTINC:
4329 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4330 MO_LEUW);
4331 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4332 break;
4333 case OPC2_32_BO_ST_H_PREINC:
4334 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4335 break;
4336 case OPC2_32_BO_ST_Q_SHORTOFF:
4337 temp = tcg_temp_new();
4338 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4339 gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4340 break;
4341 case OPC2_32_BO_ST_Q_POSTINC:
4342 temp = tcg_temp_new();
4343 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4344 tcg_gen_qemu_st_tl(temp, cpu_gpr_a[r2], ctx->mem_idx,
4345 MO_LEUW);
4346 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4347 break;
4348 case OPC2_32_BO_ST_Q_PREINC:
4349 temp = tcg_temp_new();
4350 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4351 gen_st_preincr(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4352 break;
4353 case OPC2_32_BO_ST_W_SHORTOFF:
4354 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4355 break;
4356 case OPC2_32_BO_ST_W_POSTINC:
4357 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4358 MO_LEUL);
4359 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4360 break;
4361 case OPC2_32_BO_ST_W_PREINC:
4362 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4363 break;
4364 default:
4365 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4366 }
4367 }
4368
decode_bo_addrmode_bitreverse_circular(DisasContext * ctx)4369 static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx)
4370 {
4371 uint32_t op2;
4372 uint32_t off10;
4373 int32_t r1, r2;
4374 TCGv temp, temp2, t_off10;
4375
4376 r1 = MASK_OP_BO_S1D(ctx->opcode);
4377 r2 = MASK_OP_BO_S2(ctx->opcode);
4378 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4379 op2 = MASK_OP_BO_OP2(ctx->opcode);
4380
4381 temp = tcg_temp_new();
4382 temp2 = tcg_temp_new();
4383 t_off10 = tcg_constant_i32(off10);
4384 CHECK_REG_PAIR(r2);
4385 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
4386 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4387
4388 switch (op2) {
4389 case OPC2_32_BO_CACHEA_WI_BR:
4390 case OPC2_32_BO_CACHEA_W_BR:
4391 case OPC2_32_BO_CACHEA_I_BR:
4392 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4393 break;
4394 case OPC2_32_BO_CACHEA_WI_CIRC:
4395 case OPC2_32_BO_CACHEA_W_CIRC:
4396 case OPC2_32_BO_CACHEA_I_CIRC:
4397 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4398 break;
4399 case OPC2_32_BO_ST_A_BR:
4400 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4401 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4402 break;
4403 case OPC2_32_BO_ST_A_CIRC:
4404 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4405 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4406 break;
4407 case OPC2_32_BO_ST_B_BR:
4408 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4409 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4410 break;
4411 case OPC2_32_BO_ST_B_CIRC:
4412 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4413 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4414 break;
4415 case OPC2_32_BO_ST_D_BR:
4416 CHECK_REG_PAIR(r1);
4417 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
4418 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4419 break;
4420 case OPC2_32_BO_ST_D_CIRC:
4421 CHECK_REG_PAIR(r1);
4422 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4423 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4424 tcg_gen_addi_tl(temp, temp, 4);
4425 tcg_gen_rem_tl(temp, temp, temp2);
4426 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4427 tcg_gen_qemu_st_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4428 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4429 break;
4430 case OPC2_32_BO_ST_DA_BR:
4431 CHECK_REG_PAIR(r1);
4432 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
4433 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4434 break;
4435 case OPC2_32_BO_ST_DA_CIRC:
4436 CHECK_REG_PAIR(r1);
4437 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4438 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4439 tcg_gen_addi_tl(temp, temp, 4);
4440 tcg_gen_rem_tl(temp, temp, temp2);
4441 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4442 tcg_gen_qemu_st_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4443 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4444 break;
4445 case OPC2_32_BO_ST_H_BR:
4446 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4447 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4448 break;
4449 case OPC2_32_BO_ST_H_CIRC:
4450 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4451 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4452 break;
4453 case OPC2_32_BO_ST_Q_BR:
4454 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4455 tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW);
4456 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4457 break;
4458 case OPC2_32_BO_ST_Q_CIRC:
4459 tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4460 tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW);
4461 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4462 break;
4463 case OPC2_32_BO_ST_W_BR:
4464 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4465 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4466 break;
4467 case OPC2_32_BO_ST_W_CIRC:
4468 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4469 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4470 break;
4471 default:
4472 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4473 }
4474 }
4475
decode_bo_addrmode_ld_post_pre_base(DisasContext * ctx)4476 static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx)
4477 {
4478 uint32_t op2;
4479 uint32_t off10;
4480 int32_t r1, r2;
4481 TCGv temp;
4482
4483 r1 = MASK_OP_BO_S1D(ctx->opcode);
4484 r2 = MASK_OP_BO_S2(ctx->opcode);
4485 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4486 op2 = MASK_OP_BO_OP2(ctx->opcode);
4487
4488 switch (op2) {
4489 case OPC2_32_BO_LD_A_SHORTOFF:
4490 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4491 break;
4492 case OPC2_32_BO_LD_A_POSTINC:
4493 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4494 MO_LEUL);
4495 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4496 break;
4497 case OPC2_32_BO_LD_A_PREINC:
4498 gen_ld_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4499 break;
4500 case OPC2_32_BO_LD_B_SHORTOFF:
4501 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4502 break;
4503 case OPC2_32_BO_LD_B_POSTINC:
4504 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4505 MO_SB);
4506 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4507 break;
4508 case OPC2_32_BO_LD_B_PREINC:
4509 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4510 break;
4511 case OPC2_32_BO_LD_BU_SHORTOFF:
4512 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4513 break;
4514 case OPC2_32_BO_LD_BU_POSTINC:
4515 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4516 MO_UB);
4517 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4518 break;
4519 case OPC2_32_BO_LD_BU_PREINC:
4520 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4521 break;
4522 case OPC2_32_BO_LD_D_SHORTOFF:
4523 CHECK_REG_PAIR(r1);
4524 gen_offset_ld_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4525 off10, ctx);
4526 break;
4527 case OPC2_32_BO_LD_D_POSTINC:
4528 CHECK_REG_PAIR(r1);
4529 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
4530 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4531 break;
4532 case OPC2_32_BO_LD_D_PREINC:
4533 CHECK_REG_PAIR(r1);
4534 temp = tcg_temp_new();
4535 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4536 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4537 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4538 break;
4539 case OPC2_32_BO_LD_DA_SHORTOFF:
4540 CHECK_REG_PAIR(r1);
4541 gen_offset_ld_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4542 off10, ctx);
4543 break;
4544 case OPC2_32_BO_LD_DA_POSTINC:
4545 CHECK_REG_PAIR(r1);
4546 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
4547 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4548 break;
4549 case OPC2_32_BO_LD_DA_PREINC:
4550 CHECK_REG_PAIR(r1);
4551 temp = tcg_temp_new();
4552 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4553 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4554 tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4555 break;
4556 case OPC2_32_BO_LD_H_SHORTOFF:
4557 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
4558 break;
4559 case OPC2_32_BO_LD_H_POSTINC:
4560 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4561 MO_LESW);
4562 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4563 break;
4564 case OPC2_32_BO_LD_H_PREINC:
4565 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
4566 break;
4567 case OPC2_32_BO_LD_HU_SHORTOFF:
4568 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4569 break;
4570 case OPC2_32_BO_LD_HU_POSTINC:
4571 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4572 MO_LEUW);
4573 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4574 break;
4575 case OPC2_32_BO_LD_HU_PREINC:
4576 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4577 break;
4578 case OPC2_32_BO_LD_Q_SHORTOFF:
4579 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4580 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4581 break;
4582 case OPC2_32_BO_LD_Q_POSTINC:
4583 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4584 MO_LEUW);
4585 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4586 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4587 break;
4588 case OPC2_32_BO_LD_Q_PREINC:
4589 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4590 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4591 break;
4592 case OPC2_32_BO_LD_W_SHORTOFF:
4593 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4594 break;
4595 case OPC2_32_BO_LD_W_POSTINC:
4596 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4597 MO_LEUL);
4598 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4599 break;
4600 case OPC2_32_BO_LD_W_PREINC:
4601 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4602 break;
4603 default:
4604 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4605 }
4606 }
4607
decode_bo_addrmode_ld_bitreverse_circular(DisasContext * ctx)4608 static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx)
4609 {
4610 uint32_t op2;
4611 uint32_t off10;
4612 int r1, r2;
4613 TCGv temp, temp2, t_off10;
4614
4615 r1 = MASK_OP_BO_S1D(ctx->opcode);
4616 r2 = MASK_OP_BO_S2(ctx->opcode);
4617 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4618 op2 = MASK_OP_BO_OP2(ctx->opcode);
4619
4620 temp = tcg_temp_new();
4621 temp2 = tcg_temp_new();
4622 t_off10 = tcg_constant_i32(off10);
4623 CHECK_REG_PAIR(r2);
4624 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
4625 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4626
4627
4628 switch (op2) {
4629 case OPC2_32_BO_LD_A_BR:
4630 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4631 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4632 break;
4633 case OPC2_32_BO_LD_A_CIRC:
4634 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4635 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4636 break;
4637 case OPC2_32_BO_LD_B_BR:
4638 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
4639 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4640 break;
4641 case OPC2_32_BO_LD_B_CIRC:
4642 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
4643 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4644 break;
4645 case OPC2_32_BO_LD_BU_BR:
4646 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4647 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4648 break;
4649 case OPC2_32_BO_LD_BU_CIRC:
4650 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4651 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4652 break;
4653 case OPC2_32_BO_LD_D_BR:
4654 CHECK_REG_PAIR(r1);
4655 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
4656 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4657 break;
4658 case OPC2_32_BO_LD_D_CIRC:
4659 CHECK_REG_PAIR(r1);
4660 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4661 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4662 tcg_gen_addi_tl(temp, temp, 4);
4663 tcg_gen_rem_tl(temp, temp, temp2);
4664 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4665 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4666 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4667 break;
4668 case OPC2_32_BO_LD_DA_BR:
4669 CHECK_REG_PAIR(r1);
4670 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
4671 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4672 break;
4673 case OPC2_32_BO_LD_DA_CIRC:
4674 CHECK_REG_PAIR(r1);
4675 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4676 tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
4677 tcg_gen_addi_tl(temp, temp, 4);
4678 tcg_gen_rem_tl(temp, temp, temp2);
4679 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4680 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL);
4681 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4682 break;
4683 case OPC2_32_BO_LD_H_BR:
4684 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
4685 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4686 break;
4687 case OPC2_32_BO_LD_H_CIRC:
4688 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
4689 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4690 break;
4691 case OPC2_32_BO_LD_HU_BR:
4692 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4693 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4694 break;
4695 case OPC2_32_BO_LD_HU_CIRC:
4696 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4697 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4698 break;
4699 case OPC2_32_BO_LD_Q_BR:
4700 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4701 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4702 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4703 break;
4704 case OPC2_32_BO_LD_Q_CIRC:
4705 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4706 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4707 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4708 break;
4709 case OPC2_32_BO_LD_W_BR:
4710 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4711 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4712 break;
4713 case OPC2_32_BO_LD_W_CIRC:
4714 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4715 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4716 break;
4717 default:
4718 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4719 }
4720 }
4721
decode_bo_addrmode_stctx_post_pre_base(DisasContext * ctx)4722 static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx)
4723 {
4724 uint32_t op2;
4725 uint32_t off10;
4726 int r1, r2;
4727
4728 TCGv temp;
4729
4730 r1 = MASK_OP_BO_S1D(ctx->opcode);
4731 r2 = MASK_OP_BO_S2(ctx->opcode);
4732 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4733 op2 = MASK_OP_BO_OP2(ctx->opcode);
4734
4735
4736 temp = tcg_temp_new();
4737
4738 switch (op2) {
4739 case OPC2_32_BO_LDLCX_SHORTOFF:
4740 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4741 gen_helper_ldlcx(tcg_env, temp);
4742 break;
4743 case OPC2_32_BO_LDMST_SHORTOFF:
4744 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4745 gen_ldmst(ctx, r1, temp);
4746 break;
4747 case OPC2_32_BO_LDMST_POSTINC:
4748 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
4749 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4750 break;
4751 case OPC2_32_BO_LDMST_PREINC:
4752 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4753 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
4754 break;
4755 case OPC2_32_BO_LDUCX_SHORTOFF:
4756 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4757 gen_helper_lducx(tcg_env, temp);
4758 break;
4759 case OPC2_32_BO_LEA_SHORTOFF:
4760 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], off10);
4761 break;
4762 case OPC2_32_BO_STLCX_SHORTOFF:
4763 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4764 gen_helper_stlcx(tcg_env, temp);
4765 break;
4766 case OPC2_32_BO_STUCX_SHORTOFF:
4767 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4768 gen_helper_stucx(tcg_env, temp);
4769 break;
4770 case OPC2_32_BO_SWAP_W_SHORTOFF:
4771 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4772 gen_swap(ctx, r1, temp);
4773 break;
4774 case OPC2_32_BO_SWAP_W_POSTINC:
4775 gen_swap(ctx, r1, cpu_gpr_a[r2]);
4776 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4777 break;
4778 case OPC2_32_BO_SWAP_W_PREINC:
4779 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4780 gen_swap(ctx, r1, cpu_gpr_a[r2]);
4781 break;
4782 case OPC2_32_BO_CMPSWAP_W_SHORTOFF:
4783 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4784 gen_cmpswap(ctx, r1, temp);
4785 break;
4786 case OPC2_32_BO_CMPSWAP_W_POSTINC:
4787 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
4788 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4789 break;
4790 case OPC2_32_BO_CMPSWAP_W_PREINC:
4791 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4792 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
4793 break;
4794 case OPC2_32_BO_SWAPMSK_W_SHORTOFF:
4795 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4796 gen_swapmsk(ctx, r1, temp);
4797 break;
4798 case OPC2_32_BO_SWAPMSK_W_POSTINC:
4799 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
4800 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4801 break;
4802 case OPC2_32_BO_SWAPMSK_W_PREINC:
4803 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4804 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
4805 break;
4806 default:
4807 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4808 }
4809 }
4810
decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext * ctx)4811 static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx)
4812 {
4813 uint32_t op2;
4814 uint32_t off10;
4815 int r1, r2;
4816 TCGv temp, temp2, t_off10;
4817
4818 r1 = MASK_OP_BO_S1D(ctx->opcode);
4819 r2 = MASK_OP_BO_S2(ctx->opcode);
4820 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4821 op2 = MASK_OP_BO_OP2(ctx->opcode);
4822
4823 temp = tcg_temp_new();
4824 temp2 = tcg_temp_new();
4825 t_off10 = tcg_constant_i32(off10);
4826 CHECK_REG_PAIR(r2);
4827 tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
4828 tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
4829
4830 switch (op2) {
4831 case OPC2_32_BO_LDMST_BR:
4832 gen_ldmst(ctx, r1, temp2);
4833 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4834 break;
4835 case OPC2_32_BO_LDMST_CIRC:
4836 gen_ldmst(ctx, r1, temp2);
4837 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4838 break;
4839 case OPC2_32_BO_SWAP_W_BR:
4840 gen_swap(ctx, r1, temp2);
4841 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4842 break;
4843 case OPC2_32_BO_SWAP_W_CIRC:
4844 gen_swap(ctx, r1, temp2);
4845 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4846 break;
4847 case OPC2_32_BO_CMPSWAP_W_BR:
4848 gen_cmpswap(ctx, r1, temp2);
4849 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4850 break;
4851 case OPC2_32_BO_CMPSWAP_W_CIRC:
4852 gen_cmpswap(ctx, r1, temp2);
4853 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4854 break;
4855 case OPC2_32_BO_SWAPMSK_W_BR:
4856 gen_swapmsk(ctx, r1, temp2);
4857 gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
4858 break;
4859 case OPC2_32_BO_SWAPMSK_W_CIRC:
4860 gen_swapmsk(ctx, r1, temp2);
4861 gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], t_off10);
4862 break;
4863 default:
4864 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4865 }
4866 }
4867
decode_bol_opc(DisasContext * ctx,int32_t op1)4868 static void decode_bol_opc(DisasContext *ctx, int32_t op1)
4869 {
4870 int r1, r2;
4871 int32_t address;
4872 TCGv temp;
4873
4874 r1 = MASK_OP_BOL_S1D(ctx->opcode);
4875 r2 = MASK_OP_BOL_S2(ctx->opcode);
4876 address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);
4877
4878 switch (op1) {
4879 case OPC1_32_BOL_LD_A_LONGOFF:
4880 temp = tcg_temp_new();
4881 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
4882 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
4883 break;
4884 case OPC1_32_BOL_LD_W_LONGOFF:
4885 temp = tcg_temp_new();
4886 tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
4887 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
4888 break;
4889 case OPC1_32_BOL_LEA_LONGOFF:
4890 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
4891 break;
4892 case OPC1_32_BOL_ST_A_LONGOFF:
4893 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4894 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
4895 } else {
4896 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4897 }
4898 break;
4899 case OPC1_32_BOL_ST_W_LONGOFF:
4900 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
4901 break;
4902 case OPC1_32_BOL_LD_B_LONGOFF:
4903 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4904 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
4905 } else {
4906 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4907 }
4908 break;
4909 case OPC1_32_BOL_LD_BU_LONGOFF:
4910 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4911 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);
4912 } else {
4913 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4914 }
4915 break;
4916 case OPC1_32_BOL_LD_H_LONGOFF:
4917 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4918 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
4919 } else {
4920 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4921 }
4922 break;
4923 case OPC1_32_BOL_LD_HU_LONGOFF:
4924 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4925 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);
4926 } else {
4927 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4928 }
4929 break;
4930 case OPC1_32_BOL_ST_B_LONGOFF:
4931 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4932 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
4933 } else {
4934 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4935 }
4936 break;
4937 case OPC1_32_BOL_ST_H_LONGOFF:
4938 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4939 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
4940 } else {
4941 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4942 }
4943 break;
4944 default:
4945 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4946 }
4947 }
4948
4949 /* RC format */
decode_rc_logical_shift(DisasContext * ctx)4950 static void decode_rc_logical_shift(DisasContext *ctx)
4951 {
4952 uint32_t op2;
4953 int r1, r2;
4954 int32_t const9;
4955 TCGv temp;
4956
4957 r2 = MASK_OP_RC_D(ctx->opcode);
4958 r1 = MASK_OP_RC_S1(ctx->opcode);
4959 const9 = MASK_OP_RC_CONST9(ctx->opcode);
4960 op2 = MASK_OP_RC_OP2(ctx->opcode);
4961
4962 switch (op2) {
4963 case OPC2_32_RC_AND:
4964 tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
4965 break;
4966 case OPC2_32_RC_ANDN:
4967 tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
4968 break;
4969 case OPC2_32_RC_NAND:
4970 temp = tcg_temp_new();
4971 tcg_gen_movi_tl(temp, const9);
4972 tcg_gen_nand_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
4973 break;
4974 case OPC2_32_RC_NOR:
4975 temp = tcg_temp_new();
4976 tcg_gen_movi_tl(temp, const9);
4977 tcg_gen_nor_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
4978 break;
4979 case OPC2_32_RC_OR:
4980 tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
4981 break;
4982 case OPC2_32_RC_ORN:
4983 tcg_gen_ori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
4984 break;
4985 case OPC2_32_RC_SH:
4986 const9 = sextract32(const9, 0, 6);
4987 gen_shi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
4988 break;
4989 case OPC2_32_RC_SH_H:
4990 const9 = sextract32(const9, 0, 5);
4991 gen_sh_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
4992 break;
4993 case OPC2_32_RC_SHA:
4994 const9 = sextract32(const9, 0, 6);
4995 gen_shaci(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
4996 break;
4997 case OPC2_32_RC_SHA_H:
4998 const9 = sextract32(const9, 0, 5);
4999 gen_sha_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5000 break;
5001 case OPC2_32_RC_SHAS:
5002 gen_shasi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5003 break;
5004 case OPC2_32_RC_XNOR:
5005 tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5006 tcg_gen_not_tl(cpu_gpr_d[r2], cpu_gpr_d[r2]);
5007 break;
5008 case OPC2_32_RC_XOR:
5009 tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5010 break;
5011 case OPC2_32_RC_SHUFFLE:
5012 if (has_feature(ctx, TRICORE_FEATURE_162)) {
5013 temp = tcg_constant_i32(const9);
5014 gen_helper_shuffle(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
5015 } else {
5016 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5017 }
5018 break;
5019 default:
5020 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5021 }
5022 }
5023
decode_rc_accumulator(DisasContext * ctx)5024 static void decode_rc_accumulator(DisasContext *ctx)
5025 {
5026 uint32_t op2;
5027 int r1, r2;
5028 int16_t const9;
5029
5030 TCGv temp;
5031
5032 r2 = MASK_OP_RC_D(ctx->opcode);
5033 r1 = MASK_OP_RC_S1(ctx->opcode);
5034 const9 = MASK_OP_RC_CONST9_SEXT(ctx->opcode);
5035
5036 op2 = MASK_OP_RC_OP2(ctx->opcode);
5037
5038 temp = tcg_temp_new();
5039
5040 switch (op2) {
5041 case OPC2_32_RC_ABSDIF:
5042 gen_absdifi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5043 break;
5044 case OPC2_32_RC_ABSDIFS:
5045 gen_absdifsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5046 break;
5047 case OPC2_32_RC_ADD:
5048 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5049 break;
5050 case OPC2_32_RC_ADDC:
5051 gen_addci_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5052 break;
5053 case OPC2_32_RC_ADDS:
5054 gen_addsi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5055 break;
5056 case OPC2_32_RC_ADDS_U:
5057 gen_addsui(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5058 break;
5059 case OPC2_32_RC_ADDX:
5060 gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5061 break;
5062 case OPC2_32_RC_AND_EQ:
5063 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5064 const9, &tcg_gen_and_tl);
5065 break;
5066 case OPC2_32_RC_AND_GE:
5067 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5068 const9, &tcg_gen_and_tl);
5069 break;
5070 case OPC2_32_RC_AND_GE_U:
5071 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5072 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5073 const9, &tcg_gen_and_tl);
5074 break;
5075 case OPC2_32_RC_AND_LT:
5076 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5077 const9, &tcg_gen_and_tl);
5078 break;
5079 case OPC2_32_RC_AND_LT_U:
5080 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5081 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5082 const9, &tcg_gen_and_tl);
5083 break;
5084 case OPC2_32_RC_AND_NE:
5085 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5086 const9, &tcg_gen_and_tl);
5087 break;
5088 case OPC2_32_RC_EQ:
5089 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5090 break;
5091 case OPC2_32_RC_EQANY_B:
5092 gen_eqany_bi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5093 break;
5094 case OPC2_32_RC_EQANY_H:
5095 gen_eqany_hi(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5096 break;
5097 case OPC2_32_RC_GE:
5098 tcg_gen_setcondi_tl(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5099 break;
5100 case OPC2_32_RC_GE_U:
5101 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5102 tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5103 break;
5104 case OPC2_32_RC_LT:
5105 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5106 break;
5107 case OPC2_32_RC_LT_U:
5108 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5109 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5110 break;
5111 case OPC2_32_RC_MAX:
5112 tcg_gen_movi_tl(temp, const9);
5113 tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5114 cpu_gpr_d[r1], temp);
5115 break;
5116 case OPC2_32_RC_MAX_U:
5117 tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
5118 tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5119 cpu_gpr_d[r1], temp);
5120 break;
5121 case OPC2_32_RC_MIN:
5122 tcg_gen_movi_tl(temp, const9);
5123 tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5124 cpu_gpr_d[r1], temp);
5125 break;
5126 case OPC2_32_RC_MIN_U:
5127 tcg_gen_movi_tl(temp, MASK_OP_RC_CONST9(ctx->opcode));
5128 tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], temp,
5129 cpu_gpr_d[r1], temp);
5130 break;
5131 case OPC2_32_RC_NE:
5132 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5133 break;
5134 case OPC2_32_RC_OR_EQ:
5135 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5136 const9, &tcg_gen_or_tl);
5137 break;
5138 case OPC2_32_RC_OR_GE:
5139 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5140 const9, &tcg_gen_or_tl);
5141 break;
5142 case OPC2_32_RC_OR_GE_U:
5143 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5144 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5145 const9, &tcg_gen_or_tl);
5146 break;
5147 case OPC2_32_RC_OR_LT:
5148 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5149 const9, &tcg_gen_or_tl);
5150 break;
5151 case OPC2_32_RC_OR_LT_U:
5152 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5153 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5154 const9, &tcg_gen_or_tl);
5155 break;
5156 case OPC2_32_RC_OR_NE:
5157 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5158 const9, &tcg_gen_or_tl);
5159 break;
5160 case OPC2_32_RC_RSUB:
5161 tcg_gen_movi_tl(temp, const9);
5162 gen_sub_d(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5163 break;
5164 case OPC2_32_RC_RSUBS:
5165 tcg_gen_movi_tl(temp, const9);
5166 gen_subs(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5167 break;
5168 case OPC2_32_RC_RSUBS_U:
5169 tcg_gen_movi_tl(temp, const9);
5170 gen_subsu(cpu_gpr_d[r2], temp, cpu_gpr_d[r1]);
5171 break;
5172 case OPC2_32_RC_SH_EQ:
5173 gen_sh_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5174 break;
5175 case OPC2_32_RC_SH_GE:
5176 gen_sh_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5177 break;
5178 case OPC2_32_RC_SH_GE_U:
5179 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5180 gen_sh_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5181 break;
5182 case OPC2_32_RC_SH_LT:
5183 gen_sh_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5184 break;
5185 case OPC2_32_RC_SH_LT_U:
5186 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5187 gen_sh_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5188 break;
5189 case OPC2_32_RC_SH_NE:
5190 gen_sh_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5191 break;
5192 case OPC2_32_RC_XOR_EQ:
5193 gen_accumulating_condi(TCG_COND_EQ, cpu_gpr_d[r2], cpu_gpr_d[r1],
5194 const9, &tcg_gen_xor_tl);
5195 break;
5196 case OPC2_32_RC_XOR_GE:
5197 gen_accumulating_condi(TCG_COND_GE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5198 const9, &tcg_gen_xor_tl);
5199 break;
5200 case OPC2_32_RC_XOR_GE_U:
5201 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5202 gen_accumulating_condi(TCG_COND_GEU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5203 const9, &tcg_gen_xor_tl);
5204 break;
5205 case OPC2_32_RC_XOR_LT:
5206 gen_accumulating_condi(TCG_COND_LT, cpu_gpr_d[r2], cpu_gpr_d[r1],
5207 const9, &tcg_gen_xor_tl);
5208 break;
5209 case OPC2_32_RC_XOR_LT_U:
5210 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5211 gen_accumulating_condi(TCG_COND_LTU, cpu_gpr_d[r2], cpu_gpr_d[r1],
5212 const9, &tcg_gen_xor_tl);
5213 break;
5214 case OPC2_32_RC_XOR_NE:
5215 gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
5216 const9, &tcg_gen_xor_tl);
5217 break;
5218 default:
5219 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5220 }
5221 }
5222
decode_rc_serviceroutine(DisasContext * ctx)5223 static void decode_rc_serviceroutine(DisasContext *ctx)
5224 {
5225 uint32_t op2;
5226 uint32_t const9;
5227
5228 op2 = MASK_OP_RC_OP2(ctx->opcode);
5229 const9 = MASK_OP_RC_CONST9(ctx->opcode);
5230
5231 switch (op2) {
5232 case OPC2_32_RC_BISR:
5233 if (ctx->priv == TRICORE_PRIV_SM) {
5234 gen_helper_1arg(bisr, const9);
5235 } else {
5236 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
5237 }
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
decode_rc_mul(DisasContext * ctx)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 */
decode_rcpw_insert(DisasContext * ctx)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 /* tcg_gen_deposit_tl() does not handle the case of width = 0 */
5311 if (width == 0) {
5312 tcg_gen_mov_tl(cpu_gpr_d[r2], cpu_gpr_d[r1]);
5313 /* if pos + width > 32 undefined result */
5314 } else if (pos + width <= 32) {
5315 temp = tcg_constant_i32(const4);
5316 tcg_gen_deposit_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, pos, width);
5317 }
5318 break;
5319 default:
5320 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5321 }
5322 }
5323
5324 /* RCRW format */
5325
decode_rcrw_insert(DisasContext * ctx)5326 static void decode_rcrw_insert(DisasContext *ctx)
5327 {
5328 uint32_t op2;
5329 int r1, r3, r4;
5330 int32_t width, const4;
5331
5332 TCGv temp, temp2, temp3;
5333
5334 op2 = MASK_OP_RCRW_OP2(ctx->opcode);
5335 r1 = MASK_OP_RCRW_S1(ctx->opcode);
5336 r3 = MASK_OP_RCRW_S3(ctx->opcode);
5337 r4 = MASK_OP_RCRW_D(ctx->opcode);
5338 width = MASK_OP_RCRW_WIDTH(ctx->opcode);
5339 const4 = MASK_OP_RCRW_CONST4(ctx->opcode);
5340
5341 temp = tcg_temp_new();
5342 temp2 = tcg_temp_new();
5343
5344 switch (op2) {
5345 case OPC2_32_RCRW_IMASK:
5346 CHECK_REG_PAIR(r4);
5347 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
5348 tcg_gen_movi_tl(temp2, (1 << width) - 1);
5349 tcg_gen_shl_tl(cpu_gpr_d[r4 + 1], temp2, temp);
5350 tcg_gen_movi_tl(temp2, const4);
5351 tcg_gen_shl_tl(cpu_gpr_d[r4], temp2, temp);
5352 break;
5353 case OPC2_32_RCRW_INSERT:
5354 temp3 = tcg_temp_new();
5355
5356 tcg_gen_movi_tl(temp, width);
5357 tcg_gen_movi_tl(temp2, const4);
5358 tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
5359 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], temp2, temp, temp3);
5360 break;
5361 default:
5362 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5363 }
5364 }
5365
5366 /* RCR format */
5367
decode_rcr_cond_select(DisasContext * ctx)5368 static void decode_rcr_cond_select(DisasContext *ctx)
5369 {
5370 uint32_t op2;
5371 int r1, r3, r4;
5372 int32_t const9;
5373
5374 TCGv temp, temp2;
5375
5376 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5377 r1 = MASK_OP_RCR_S1(ctx->opcode);
5378 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5379 r3 = MASK_OP_RCR_S3(ctx->opcode);
5380 r4 = MASK_OP_RCR_D(ctx->opcode);
5381
5382 switch (op2) {
5383 case OPC2_32_RCR_CADD:
5384 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const9, cpu_gpr_d[r4],
5385 cpu_gpr_d[r3]);
5386 break;
5387 case OPC2_32_RCR_CADDN:
5388 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const9, cpu_gpr_d[r4],
5389 cpu_gpr_d[r3]);
5390 break;
5391 case OPC2_32_RCR_SEL:
5392 temp = tcg_constant_i32(0);
5393 temp2 = tcg_constant_i32(const9);
5394 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
5395 cpu_gpr_d[r1], temp2);
5396 break;
5397 case OPC2_32_RCR_SELN:
5398 temp = tcg_constant_i32(0);
5399 temp2 = tcg_constant_i32(const9);
5400 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
5401 cpu_gpr_d[r1], temp2);
5402 break;
5403 default:
5404 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5405 }
5406 }
5407
decode_rcr_madd(DisasContext * ctx)5408 static void decode_rcr_madd(DisasContext *ctx)
5409 {
5410 uint32_t op2;
5411 int r1, r3, r4;
5412 int32_t const9;
5413
5414
5415 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5416 r1 = MASK_OP_RCR_S1(ctx->opcode);
5417 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5418 r3 = MASK_OP_RCR_S3(ctx->opcode);
5419 r4 = MASK_OP_RCR_D(ctx->opcode);
5420
5421 switch (op2) {
5422 case OPC2_32_RCR_MADD_32:
5423 gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5424 break;
5425 case OPC2_32_RCR_MADD_64:
5426 CHECK_REG_PAIR(r4);
5427 CHECK_REG_PAIR(r3);
5428 gen_maddi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5429 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5430 break;
5431 case OPC2_32_RCR_MADDS_32:
5432 gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5433 break;
5434 case OPC2_32_RCR_MADDS_64:
5435 CHECK_REG_PAIR(r4);
5436 CHECK_REG_PAIR(r3);
5437 gen_maddsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5438 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5439 break;
5440 case OPC2_32_RCR_MADD_U_64:
5441 CHECK_REG_PAIR(r4);
5442 CHECK_REG_PAIR(r3);
5443 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5444 gen_maddui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5445 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5446 break;
5447 case OPC2_32_RCR_MADDS_U_32:
5448 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5449 gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5450 break;
5451 case OPC2_32_RCR_MADDS_U_64:
5452 CHECK_REG_PAIR(r4);
5453 CHECK_REG_PAIR(r3);
5454 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5455 gen_maddsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5456 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5457 break;
5458 default:
5459 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5460 }
5461 }
5462
decode_rcr_msub(DisasContext * ctx)5463 static void decode_rcr_msub(DisasContext *ctx)
5464 {
5465 uint32_t op2;
5466 int r1, r3, r4;
5467 int32_t const9;
5468
5469
5470 op2 = MASK_OP_RCR_OP2(ctx->opcode);
5471 r1 = MASK_OP_RCR_S1(ctx->opcode);
5472 const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
5473 r3 = MASK_OP_RCR_S3(ctx->opcode);
5474 r4 = MASK_OP_RCR_D(ctx->opcode);
5475
5476 switch (op2) {
5477 case OPC2_32_RCR_MSUB_32:
5478 gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5479 break;
5480 case OPC2_32_RCR_MSUB_64:
5481 CHECK_REG_PAIR(r4);
5482 CHECK_REG_PAIR(r3);
5483 gen_msubi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5484 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5485 break;
5486 case OPC2_32_RCR_MSUBS_32:
5487 gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5488 break;
5489 case OPC2_32_RCR_MSUBS_64:
5490 CHECK_REG_PAIR(r4);
5491 CHECK_REG_PAIR(r3);
5492 gen_msubsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5493 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5494 break;
5495 case OPC2_32_RCR_MSUB_U_64:
5496 CHECK_REG_PAIR(r4);
5497 CHECK_REG_PAIR(r3);
5498 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5499 gen_msubui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5500 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5501 break;
5502 case OPC2_32_RCR_MSUBS_U_32:
5503 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5504 gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
5505 break;
5506 case OPC2_32_RCR_MSUBS_U_64:
5507 CHECK_REG_PAIR(r4);
5508 CHECK_REG_PAIR(r3);
5509 const9 = MASK_OP_RCR_CONST9(ctx->opcode);
5510 gen_msubsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
5511 cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
5512 break;
5513 default:
5514 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5515 }
5516 }
5517
5518 /* RLC format */
5519
decode_rlc_opc(DisasContext * ctx,uint32_t op1)5520 static void decode_rlc_opc(DisasContext *ctx,
5521 uint32_t op1)
5522 {
5523 int32_t const16;
5524 int r1, r2;
5525
5526 const16 = MASK_OP_RLC_CONST16_SEXT(ctx->opcode);
5527 r1 = MASK_OP_RLC_S1(ctx->opcode);
5528 r2 = MASK_OP_RLC_D(ctx->opcode);
5529
5530 switch (op1) {
5531 case OPC1_32_RLC_ADDI:
5532 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const16);
5533 break;
5534 case OPC1_32_RLC_ADDIH:
5535 gen_addi_d(cpu_gpr_d[r2], cpu_gpr_d[r1], const16 << 16);
5536 break;
5537 case OPC1_32_RLC_ADDIH_A:
5538 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
5539 break;
5540 case OPC1_32_RLC_MFCR:
5541 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
5542 gen_mfcr(ctx, cpu_gpr_d[r2], const16);
5543 break;
5544 case OPC1_32_RLC_MOV:
5545 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
5546 break;
5547 case OPC1_32_RLC_MOV_64:
5548 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5549 CHECK_REG_PAIR(r2);
5550 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
5551 tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15);
5552 } else {
5553 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5554 }
5555 break;
5556 case OPC1_32_RLC_MOV_U:
5557 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
5558 tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
5559 break;
5560 case OPC1_32_RLC_MOV_H:
5561 tcg_gen_movi_tl(cpu_gpr_d[r2], const16 << 16);
5562 break;
5563 case OPC1_32_RLC_MOVH_A:
5564 tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
5565 break;
5566 case OPC1_32_RLC_MTCR:
5567 const16 = MASK_OP_RLC_CONST16(ctx->opcode);
5568 gen_mtcr(ctx, cpu_gpr_d[r1], const16);
5569 break;
5570 default:
5571 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5572 }
5573 }
5574
5575 /* RR format */
decode_rr_accumulator(DisasContext * ctx)5576 static void decode_rr_accumulator(DisasContext *ctx)
5577 {
5578 uint32_t op2;
5579 int r3, r2, r1;
5580
5581 TCGv temp;
5582
5583 r3 = MASK_OP_RR_D(ctx->opcode);
5584 r2 = MASK_OP_RR_S2(ctx->opcode);
5585 r1 = MASK_OP_RR_S1(ctx->opcode);
5586 op2 = MASK_OP_RR_OP2(ctx->opcode);
5587
5588 switch (op2) {
5589 case OPC2_32_RR_ABS:
5590 gen_abs(cpu_gpr_d[r3], cpu_gpr_d[r2]);
5591 break;
5592 case OPC2_32_RR_ABS_B:
5593 gen_helper_abs_b(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r2]);
5594 break;
5595 case OPC2_32_RR_ABS_H:
5596 gen_helper_abs_h(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r2]);
5597 break;
5598 case OPC2_32_RR_ABSDIF:
5599 gen_absdif(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5600 break;
5601 case OPC2_32_RR_ABSDIF_B:
5602 gen_helper_absdif_b(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5603 cpu_gpr_d[r2]);
5604 break;
5605 case OPC2_32_RR_ABSDIF_H:
5606 gen_helper_absdif_h(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5607 cpu_gpr_d[r2]);
5608 break;
5609 case OPC2_32_RR_ABSDIFS:
5610 gen_helper_absdif_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5611 cpu_gpr_d[r2]);
5612 break;
5613 case OPC2_32_RR_ABSDIFS_H:
5614 gen_helper_absdif_h_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5615 cpu_gpr_d[r2]);
5616 break;
5617 case OPC2_32_RR_ABSS:
5618 gen_helper_abs_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r2]);
5619 break;
5620 case OPC2_32_RR_ABSS_H:
5621 gen_helper_abs_h_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r2]);
5622 break;
5623 case OPC2_32_RR_ADD:
5624 gen_add_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5625 break;
5626 case OPC2_32_RR_ADD_B:
5627 gen_helper_add_b(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
5628 break;
5629 case OPC2_32_RR_ADD_H:
5630 gen_helper_add_h(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
5631 break;
5632 case OPC2_32_RR_ADDC:
5633 gen_addc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5634 break;
5635 case OPC2_32_RR_ADDS:
5636 gen_adds(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5637 break;
5638 case OPC2_32_RR_ADDS_H:
5639 gen_helper_add_h_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5640 cpu_gpr_d[r2]);
5641 break;
5642 case OPC2_32_RR_ADDS_HU:
5643 gen_helper_add_h_suov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5644 cpu_gpr_d[r2]);
5645 break;
5646 case OPC2_32_RR_ADDS_U:
5647 gen_helper_add_suov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5648 cpu_gpr_d[r2]);
5649 break;
5650 case OPC2_32_RR_ADDX:
5651 gen_add_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5652 break;
5653 case OPC2_32_RR_AND_EQ:
5654 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
5655 cpu_gpr_d[r2], &tcg_gen_and_tl);
5656 break;
5657 case OPC2_32_RR_AND_GE:
5658 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5659 cpu_gpr_d[r2], &tcg_gen_and_tl);
5660 break;
5661 case OPC2_32_RR_AND_GE_U:
5662 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5663 cpu_gpr_d[r2], &tcg_gen_and_tl);
5664 break;
5665 case OPC2_32_RR_AND_LT:
5666 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5667 cpu_gpr_d[r2], &tcg_gen_and_tl);
5668 break;
5669 case OPC2_32_RR_AND_LT_U:
5670 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5671 cpu_gpr_d[r2], &tcg_gen_and_tl);
5672 break;
5673 case OPC2_32_RR_AND_NE:
5674 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5675 cpu_gpr_d[r2], &tcg_gen_and_tl);
5676 break;
5677 case OPC2_32_RR_EQ:
5678 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
5679 cpu_gpr_d[r2]);
5680 break;
5681 case OPC2_32_RR_EQ_B:
5682 gen_helper_eq_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5683 break;
5684 case OPC2_32_RR_EQ_H:
5685 gen_helper_eq_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5686 break;
5687 case OPC2_32_RR_EQ_W:
5688 tcg_gen_negsetcond_tl(TCG_COND_EQ, cpu_gpr_d[r3],
5689 cpu_gpr_d[r1], cpu_gpr_d[r2]);
5690 break;
5691 case OPC2_32_RR_EQANY_B:
5692 gen_helper_eqany_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5693 break;
5694 case OPC2_32_RR_EQANY_H:
5695 gen_helper_eqany_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5696 break;
5697 case OPC2_32_RR_GE:
5698 tcg_gen_setcond_tl(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5699 cpu_gpr_d[r2]);
5700 break;
5701 case OPC2_32_RR_GE_U:
5702 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5703 cpu_gpr_d[r2]);
5704 break;
5705 case OPC2_32_RR_LT:
5706 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5707 cpu_gpr_d[r2]);
5708 break;
5709 case OPC2_32_RR_LT_U:
5710 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5711 cpu_gpr_d[r2]);
5712 break;
5713 case OPC2_32_RR_LT_B:
5714 gen_helper_lt_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5715 break;
5716 case OPC2_32_RR_LT_BU:
5717 gen_helper_lt_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5718 break;
5719 case OPC2_32_RR_LT_H:
5720 gen_helper_lt_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5721 break;
5722 case OPC2_32_RR_LT_HU:
5723 gen_helper_lt_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5724 break;
5725 case OPC2_32_RR_LT_W:
5726 tcg_gen_negsetcond_tl(TCG_COND_LT, cpu_gpr_d[r3],
5727 cpu_gpr_d[r1], cpu_gpr_d[r2]);
5728 break;
5729 case OPC2_32_RR_LT_WU:
5730 tcg_gen_negsetcond_tl(TCG_COND_LTU, cpu_gpr_d[r3],
5731 cpu_gpr_d[r1], cpu_gpr_d[r2]);
5732 break;
5733 case OPC2_32_RR_MAX:
5734 tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5735 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5736 break;
5737 case OPC2_32_RR_MAX_U:
5738 tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5739 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5740 break;
5741 case OPC2_32_RR_MAX_B:
5742 gen_helper_max_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5743 break;
5744 case OPC2_32_RR_MAX_BU:
5745 gen_helper_max_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5746 break;
5747 case OPC2_32_RR_MAX_H:
5748 gen_helper_max_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5749 break;
5750 case OPC2_32_RR_MAX_HU:
5751 gen_helper_max_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5752 break;
5753 case OPC2_32_RR_MIN:
5754 tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5755 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5756 break;
5757 case OPC2_32_RR_MIN_U:
5758 tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5759 cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5760 break;
5761 case OPC2_32_RR_MIN_B:
5762 gen_helper_min_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5763 break;
5764 case OPC2_32_RR_MIN_BU:
5765 gen_helper_min_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5766 break;
5767 case OPC2_32_RR_MIN_H:
5768 gen_helper_min_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5769 break;
5770 case OPC2_32_RR_MIN_HU:
5771 gen_helper_min_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5772 break;
5773 case OPC2_32_RR_MOV:
5774 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
5775 break;
5776 case OPC2_32_RR_MOV_64:
5777 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5778 temp = tcg_temp_new();
5779
5780 CHECK_REG_PAIR(r3);
5781 tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
5782 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
5783 tcg_gen_mov_tl(cpu_gpr_d[r3 + 1], temp);
5784 } else {
5785 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5786 }
5787 break;
5788 case OPC2_32_RR_MOVS_64:
5789 if (has_feature(ctx, TRICORE_FEATURE_16)) {
5790 CHECK_REG_PAIR(r3);
5791 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
5792 tcg_gen_sari_tl(cpu_gpr_d[r3 + 1], cpu_gpr_d[r2], 31);
5793 } else {
5794 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5795 }
5796 break;
5797 case OPC2_32_RR_NE:
5798 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5799 cpu_gpr_d[r2]);
5800 break;
5801 case OPC2_32_RR_OR_EQ:
5802 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
5803 cpu_gpr_d[r2], &tcg_gen_or_tl);
5804 break;
5805 case OPC2_32_RR_OR_GE:
5806 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5807 cpu_gpr_d[r2], &tcg_gen_or_tl);
5808 break;
5809 case OPC2_32_RR_OR_GE_U:
5810 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5811 cpu_gpr_d[r2], &tcg_gen_or_tl);
5812 break;
5813 case OPC2_32_RR_OR_LT:
5814 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5815 cpu_gpr_d[r2], &tcg_gen_or_tl);
5816 break;
5817 case OPC2_32_RR_OR_LT_U:
5818 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5819 cpu_gpr_d[r2], &tcg_gen_or_tl);
5820 break;
5821 case OPC2_32_RR_OR_NE:
5822 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5823 cpu_gpr_d[r2], &tcg_gen_or_tl);
5824 break;
5825 case OPC2_32_RR_SAT_B:
5826 gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7f, -0x80);
5827 break;
5828 case OPC2_32_RR_SAT_BU:
5829 gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xff);
5830 break;
5831 case OPC2_32_RR_SAT_H:
5832 gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7fff, -0x8000);
5833 break;
5834 case OPC2_32_RR_SAT_HU:
5835 gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xffff);
5836 break;
5837 case OPC2_32_RR_SH_EQ:
5838 gen_sh_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
5839 cpu_gpr_d[r2]);
5840 break;
5841 case OPC2_32_RR_SH_GE:
5842 gen_sh_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5843 cpu_gpr_d[r2]);
5844 break;
5845 case OPC2_32_RR_SH_GE_U:
5846 gen_sh_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5847 cpu_gpr_d[r2]);
5848 break;
5849 case OPC2_32_RR_SH_LT:
5850 gen_sh_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5851 cpu_gpr_d[r2]);
5852 break;
5853 case OPC2_32_RR_SH_LT_U:
5854 gen_sh_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5855 cpu_gpr_d[r2]);
5856 break;
5857 case OPC2_32_RR_SH_NE:
5858 gen_sh_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5859 cpu_gpr_d[r2]);
5860 break;
5861 case OPC2_32_RR_SUB:
5862 gen_sub_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5863 break;
5864 case OPC2_32_RR_SUB_B:
5865 gen_helper_sub_b(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
5866 break;
5867 case OPC2_32_RR_SUB_H:
5868 gen_helper_sub_h(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
5869 break;
5870 case OPC2_32_RR_SUBC:
5871 gen_subc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5872 break;
5873 case OPC2_32_RR_SUBS:
5874 gen_subs(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5875 break;
5876 case OPC2_32_RR_SUBS_U:
5877 gen_subsu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5878 break;
5879 case OPC2_32_RR_SUBS_H:
5880 gen_helper_sub_h_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5881 cpu_gpr_d[r2]);
5882 break;
5883 case OPC2_32_RR_SUBS_HU:
5884 gen_helper_sub_h_suov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
5885 cpu_gpr_d[r2]);
5886 break;
5887 case OPC2_32_RR_SUBX:
5888 gen_sub_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5889 break;
5890 case OPC2_32_RR_XOR_EQ:
5891 gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
5892 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5893 break;
5894 case OPC2_32_RR_XOR_GE:
5895 gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5896 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5897 break;
5898 case OPC2_32_RR_XOR_GE_U:
5899 gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5900 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5901 break;
5902 case OPC2_32_RR_XOR_LT:
5903 gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
5904 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5905 break;
5906 case OPC2_32_RR_XOR_LT_U:
5907 gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
5908 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5909 break;
5910 case OPC2_32_RR_XOR_NE:
5911 gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
5912 cpu_gpr_d[r2], &tcg_gen_xor_tl);
5913 break;
5914 default:
5915 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5916 }
5917 }
5918
decode_rr_logical_shift(DisasContext * ctx)5919 static void decode_rr_logical_shift(DisasContext *ctx)
5920 {
5921 uint32_t op2;
5922 int r3, r2, r1;
5923
5924 r3 = MASK_OP_RR_D(ctx->opcode);
5925 r2 = MASK_OP_RR_S2(ctx->opcode);
5926 r1 = MASK_OP_RR_S1(ctx->opcode);
5927 op2 = MASK_OP_RR_OP2(ctx->opcode);
5928
5929 switch (op2) {
5930 case OPC2_32_RR_AND:
5931 tcg_gen_and_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5932 break;
5933 case OPC2_32_RR_ANDN:
5934 tcg_gen_andc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5935 break;
5936 case OPC2_32_RR_CLO:
5937 tcg_gen_not_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
5938 tcg_gen_clzi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], TARGET_LONG_BITS);
5939 break;
5940 case OPC2_32_RR_CLO_H:
5941 gen_helper_clo_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
5942 break;
5943 case OPC2_32_RR_CLS:
5944 tcg_gen_clrsb_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
5945 break;
5946 case OPC2_32_RR_CLS_H:
5947 gen_helper_cls_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
5948 break;
5949 case OPC2_32_RR_CLZ:
5950 tcg_gen_clzi_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], TARGET_LONG_BITS);
5951 break;
5952 case OPC2_32_RR_CLZ_H:
5953 gen_helper_clz_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
5954 break;
5955 case OPC2_32_RR_NAND:
5956 tcg_gen_nand_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5957 break;
5958 case OPC2_32_RR_NOR:
5959 tcg_gen_nor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5960 break;
5961 case OPC2_32_RR_OR:
5962 tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5963 break;
5964 case OPC2_32_RR_ORN:
5965 tcg_gen_orc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5966 break;
5967 case OPC2_32_RR_SH:
5968 gen_helper_sh(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5969 break;
5970 case OPC2_32_RR_SH_H:
5971 gen_helper_sh_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5972 break;
5973 case OPC2_32_RR_SHA:
5974 gen_helper_sha(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
5975 break;
5976 case OPC2_32_RR_SHA_H:
5977 gen_helper_sha_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5978 break;
5979 case OPC2_32_RR_SHAS:
5980 gen_shas(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5981 break;
5982 case OPC2_32_RR_XNOR:
5983 tcg_gen_eqv_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5984 break;
5985 case OPC2_32_RR_XOR:
5986 tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
5987 break;
5988 default:
5989 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
5990 }
5991 }
5992
decode_rr_address(DisasContext * ctx)5993 static void decode_rr_address(DisasContext *ctx)
5994 {
5995 uint32_t op2, n;
5996 int r1, r2, r3;
5997 TCGv temp;
5998
5999 op2 = MASK_OP_RR_OP2(ctx->opcode);
6000 r3 = MASK_OP_RR_D(ctx->opcode);
6001 r2 = MASK_OP_RR_S2(ctx->opcode);
6002 r1 = MASK_OP_RR_S1(ctx->opcode);
6003 n = MASK_OP_RR_N(ctx->opcode);
6004
6005 switch (op2) {
6006 case OPC2_32_RR_ADD_A:
6007 tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
6008 break;
6009 case OPC2_32_RR_ADDSC_A:
6010 temp = tcg_temp_new();
6011 tcg_gen_shli_tl(temp, cpu_gpr_d[r1], n);
6012 tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r2], temp);
6013 break;
6014 case OPC2_32_RR_ADDSC_AT:
6015 temp = tcg_temp_new();
6016 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 3);
6017 tcg_gen_add_tl(temp, cpu_gpr_a[r2], temp);
6018 tcg_gen_andi_tl(cpu_gpr_a[r3], temp, 0xFFFFFFFC);
6019 break;
6020 case OPC2_32_RR_EQ_A:
6021 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1],
6022 cpu_gpr_a[r2]);
6023 break;
6024 case OPC2_32_RR_EQZ:
6025 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
6026 break;
6027 case OPC2_32_RR_GE_A:
6028 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_a[r1],
6029 cpu_gpr_a[r2]);
6030 break;
6031 case OPC2_32_RR_LT_A:
6032 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_a[r1],
6033 cpu_gpr_a[r2]);
6034 break;
6035 case OPC2_32_RR_MOV_A:
6036 tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_d[r2]);
6037 break;
6038 case OPC2_32_RR_MOV_AA:
6039 tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_a[r2]);
6040 break;
6041 case OPC2_32_RR_MOV_D:
6042 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_a[r2]);
6043 break;
6044 case OPC2_32_RR_NE_A:
6045 tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1],
6046 cpu_gpr_a[r2]);
6047 break;
6048 case OPC2_32_RR_NEZ_A:
6049 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
6050 break;
6051 case OPC2_32_RR_SUB_A:
6052 tcg_gen_sub_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
6053 break;
6054 default:
6055 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6056 }
6057 }
6058
decode_rr_idirect(DisasContext * ctx)6059 static void decode_rr_idirect(DisasContext *ctx)
6060 {
6061 uint32_t op2;
6062 int r1;
6063
6064 op2 = MASK_OP_RR_OP2(ctx->opcode);
6065 r1 = MASK_OP_RR_S1(ctx->opcode);
6066
6067 switch (op2) {
6068 case OPC2_32_RR_JI:
6069 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6070 break;
6071 case OPC2_32_RR_JLI:
6072 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6073 tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
6074 break;
6075 case OPC2_32_RR_CALLI:
6076 gen_helper_1arg(call, ctx->pc_succ_insn);
6077 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6078 break;
6079 case OPC2_32_RR_FCALLI:
6080 gen_fcall_save_ctx(ctx);
6081 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
6082 break;
6083 default:
6084 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6085 return;
6086 }
6087 ctx->base.is_jmp = DISAS_JUMP;
6088 }
6089
decode_rr_divide(DisasContext * ctx)6090 static void decode_rr_divide(DisasContext *ctx)
6091 {
6092 uint32_t op2;
6093 int r1, r2, r3;
6094
6095 TCGv temp, temp2, temp3;
6096
6097 op2 = MASK_OP_RR_OP2(ctx->opcode);
6098 r3 = MASK_OP_RR_D(ctx->opcode);
6099 r2 = MASK_OP_RR_S2(ctx->opcode);
6100 r1 = MASK_OP_RR_S1(ctx->opcode);
6101
6102 switch (op2) {
6103 case OPC2_32_RR_BMERGE:
6104 gen_helper_bmerge(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6105 break;
6106 case OPC2_32_RR_BSPLIT:
6107 CHECK_REG_PAIR(r3);
6108 gen_bsplit(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
6109 break;
6110 case OPC2_32_RR_DVINIT_B:
6111 CHECK_REG_PAIR(r3);
6112 gen_dvinit_b(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6113 cpu_gpr_d[r2]);
6114 break;
6115 case OPC2_32_RR_DVINIT_BU:
6116 temp = tcg_temp_new();
6117 temp2 = tcg_temp_new();
6118 temp3 = tcg_temp_new();
6119 CHECK_REG_PAIR(r3);
6120 tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8);
6121 /* reset av */
6122 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6123 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
6124 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
6125 tcg_gen_abs_tl(temp, temp3);
6126 tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
6127 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
6128 } else {
6129 /* overflow = (D[b] == 0) */
6130 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6131 }
6132 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6133 /* sv */
6134 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6135 /* write result */
6136 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 24);
6137 tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
6138 break;
6139 case OPC2_32_RR_DVINIT_H:
6140 CHECK_REG_PAIR(r3);
6141 gen_dvinit_h(ctx, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6142 cpu_gpr_d[r2]);
6143 break;
6144 case OPC2_32_RR_DVINIT_HU:
6145 temp = tcg_temp_new();
6146 temp2 = tcg_temp_new();
6147 temp3 = tcg_temp_new();
6148 CHECK_REG_PAIR(r3);
6149 tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16);
6150 /* reset av */
6151 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6152 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
6153 /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
6154 tcg_gen_abs_tl(temp, temp3);
6155 tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
6156 tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
6157 } else {
6158 /* overflow = (D[b] == 0) */
6159 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6160 }
6161 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6162 /* sv */
6163 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6164 /* write result */
6165 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 16);
6166 tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp3);
6167 break;
6168 case OPC2_32_RR_DVINIT:
6169 temp = tcg_temp_new();
6170 temp2 = tcg_temp_new();
6171 CHECK_REG_PAIR(r3);
6172 /* overflow = ((D[b] == 0) ||
6173 ((D[b] == 0xFFFFFFFF) && (D[a] == 0x80000000))) */
6174 tcg_gen_setcondi_tl(TCG_COND_EQ, temp, cpu_gpr_d[r2], 0xffffffff);
6175 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r1], 0x80000000);
6176 tcg_gen_and_tl(temp, temp, temp2);
6177 tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r2], 0);
6178 tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
6179 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6180 /* sv */
6181 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6182 /* reset av */
6183 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6184 /* write result */
6185 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6186 /* sign extend to high reg */
6187 tcg_gen_sari_tl(cpu_gpr_d[r3+1], cpu_gpr_d[r1], 31);
6188 break;
6189 case OPC2_32_RR_DVINIT_U:
6190 CHECK_REG_PAIR(r3);
6191 /* overflow = (D[b] == 0) */
6192 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
6193 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
6194 /* sv */
6195 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
6196 /* reset av */
6197 tcg_gen_movi_tl(cpu_PSW_AV, 0);
6198 /* write result */
6199 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6200 /* zero extend to high reg*/
6201 tcg_gen_movi_tl(cpu_gpr_d[r3+1], 0);
6202 break;
6203 case OPC2_32_RR_PARITY:
6204 gen_helper_parity(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6205 break;
6206 case OPC2_32_RR_UNPACK:
6207 CHECK_REG_PAIR(r3);
6208 gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
6209 break;
6210 case OPC2_32_RR_CRC32_B:
6211 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6212 gen_helper_crc32b(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_CRC32: /* CRC32B.W in 1.6.2 */
6218 if (has_feature(ctx, TRICORE_FEATURE_161)) {
6219 gen_helper_crc32_be(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 case OPC2_32_RR_CRC32L_W:
6225 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6226 gen_helper_crc32_le(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6227 } else {
6228 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6229 }
6230 break;
6231
6232 case OPC2_32_RR_POPCNT_W:
6233 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6234 tcg_gen_ctpop_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6235 } else {
6236 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6237 }
6238 break;
6239 case OPC2_32_RR_DIV:
6240 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6241 CHECK_REG_PAIR(r3);
6242 GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6243 cpu_gpr_d[r2]);
6244 } else {
6245 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6246 }
6247 break;
6248 case OPC2_32_RR_DIV_U:
6249 if (has_feature(ctx, TRICORE_FEATURE_16)) {
6250 CHECK_REG_PAIR(r3);
6251 GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
6252 cpu_gpr_d[r1], cpu_gpr_d[r2]);
6253 } else {
6254 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6255 }
6256 break;
6257 case OPC2_32_RR_MUL_F:
6258 gen_helper_fmul(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6259 break;
6260 case OPC2_32_RR_DIV_F:
6261 gen_helper_fdiv(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6262 break;
6263 case OPC2_32_RR_FTOHP:
6264 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6265 gen_helper_ftohp(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6266 } else {
6267 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6268 }
6269 break;
6270 case OPC2_32_RR_HPTOF:
6271 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6272 gen_helper_hptof(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6273 } else {
6274 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6275 }
6276 break;
6277 case OPC2_32_RR_CMP_F:
6278 gen_helper_fcmp(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
6279 break;
6280 case OPC2_32_RR_FTOI:
6281 gen_helper_ftoi(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6282 break;
6283 case OPC2_32_RR_ITOF:
6284 gen_helper_itof(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6285 break;
6286 case OPC2_32_RR_FTOU:
6287 gen_helper_ftou(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6288 break;
6289 case OPC2_32_RR_FTOUZ:
6290 if (has_feature(ctx, TRICORE_FEATURE_131)) {
6291 gen_helper_ftouz(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6292 } else {
6293 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6294 }
6295 break;
6296 case OPC2_32_RR_UPDFL:
6297 gen_helper_updfl(tcg_env, cpu_gpr_d[r1]);
6298 break;
6299 case OPC2_32_RR_UTOF:
6300 gen_helper_utof(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6301 break;
6302 case OPC2_32_RR_FTOIZ:
6303 gen_helper_ftoiz(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6304 break;
6305 case OPC2_32_RR_QSEED_F:
6306 gen_helper_qseed(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1]);
6307 break;
6308 default:
6309 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6310 }
6311 }
6312
6313 /* RR1 Format */
decode_rr1_mul(DisasContext * ctx)6314 static void decode_rr1_mul(DisasContext *ctx)
6315 {
6316 uint32_t op2;
6317
6318 int r1, r2, r3;
6319 TCGv n;
6320 TCGv_i64 temp64;
6321
6322 r1 = MASK_OP_RR1_S1(ctx->opcode);
6323 r2 = MASK_OP_RR1_S2(ctx->opcode);
6324 r3 = MASK_OP_RR1_D(ctx->opcode);
6325 n = tcg_constant_i32(MASK_OP_RR1_N(ctx->opcode));
6326 op2 = MASK_OP_RR1_OP2(ctx->opcode);
6327
6328 switch (op2) {
6329 case OPC2_32_RR1_MUL_H_32_LL:
6330 temp64 = tcg_temp_new_i64();
6331 CHECK_REG_PAIR(r3);
6332 GEN_HELPER_LL(mul_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 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6335 break;
6336 case OPC2_32_RR1_MUL_H_32_LU:
6337 temp64 = tcg_temp_new_i64();
6338 CHECK_REG_PAIR(r3);
6339 GEN_HELPER_LU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6340 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6341 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6342 break;
6343 case OPC2_32_RR1_MUL_H_32_UL:
6344 temp64 = tcg_temp_new_i64();
6345 CHECK_REG_PAIR(r3);
6346 GEN_HELPER_UL(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6347 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6348 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6349 break;
6350 case OPC2_32_RR1_MUL_H_32_UU:
6351 temp64 = tcg_temp_new_i64();
6352 CHECK_REG_PAIR(r3);
6353 GEN_HELPER_UU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6354 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6355 gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
6356 break;
6357 case OPC2_32_RR1_MULM_H_64_LL:
6358 temp64 = tcg_temp_new_i64();
6359 CHECK_REG_PAIR(r3);
6360 GEN_HELPER_LL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6361 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6362 /* reset V bit */
6363 tcg_gen_movi_tl(cpu_PSW_V, 0);
6364 /* reset AV bit */
6365 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6366 break;
6367 case OPC2_32_RR1_MULM_H_64_LU:
6368 temp64 = tcg_temp_new_i64();
6369 CHECK_REG_PAIR(r3);
6370 GEN_HELPER_LU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6371 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6372 /* reset V bit */
6373 tcg_gen_movi_tl(cpu_PSW_V, 0);
6374 /* reset AV bit */
6375 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6376 break;
6377 case OPC2_32_RR1_MULM_H_64_UL:
6378 temp64 = tcg_temp_new_i64();
6379 CHECK_REG_PAIR(r3);
6380 GEN_HELPER_UL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6381 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6382 /* reset V bit */
6383 tcg_gen_movi_tl(cpu_PSW_V, 0);
6384 /* reset AV bit */
6385 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6386 break;
6387 case OPC2_32_RR1_MULM_H_64_UU:
6388 temp64 = tcg_temp_new_i64();
6389 CHECK_REG_PAIR(r3);
6390 GEN_HELPER_UU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6391 tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
6392 /* reset V bit */
6393 tcg_gen_movi_tl(cpu_PSW_V, 0);
6394 /* reset AV bit */
6395 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
6396 break;
6397 case OPC2_32_RR1_MULR_H_16_LL:
6398 GEN_HELPER_LL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6399 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6400 break;
6401 case OPC2_32_RR1_MULR_H_16_LU:
6402 GEN_HELPER_LU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6403 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6404 break;
6405 case OPC2_32_RR1_MULR_H_16_UL:
6406 GEN_HELPER_UL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6407 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6408 break;
6409 case OPC2_32_RR1_MULR_H_16_UU:
6410 GEN_HELPER_UU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
6411 gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
6412 break;
6413 default:
6414 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6415 }
6416 }
6417
decode_rr1_mulq(DisasContext * ctx)6418 static void decode_rr1_mulq(DisasContext *ctx)
6419 {
6420 uint32_t op2;
6421 int r1, r2, r3;
6422 uint32_t n;
6423
6424 TCGv temp, temp2;
6425
6426 r1 = MASK_OP_RR1_S1(ctx->opcode);
6427 r2 = MASK_OP_RR1_S2(ctx->opcode);
6428 r3 = MASK_OP_RR1_D(ctx->opcode);
6429 n = MASK_OP_RR1_N(ctx->opcode);
6430 op2 = MASK_OP_RR1_OP2(ctx->opcode);
6431
6432 temp = tcg_temp_new();
6433 temp2 = tcg_temp_new();
6434
6435 switch (op2) {
6436 case OPC2_32_RR1_MUL_Q_32:
6437 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], cpu_gpr_d[r2], n, 32);
6438 break;
6439 case OPC2_32_RR1_MUL_Q_64:
6440 CHECK_REG_PAIR(r3);
6441 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
6442 n, 0);
6443 break;
6444 case OPC2_32_RR1_MUL_Q_32_L:
6445 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
6446 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
6447 break;
6448 case OPC2_32_RR1_MUL_Q_64_L:
6449 CHECK_REG_PAIR(r3);
6450 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
6451 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
6452 break;
6453 case OPC2_32_RR1_MUL_Q_32_U:
6454 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
6455 gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
6456 break;
6457 case OPC2_32_RR1_MUL_Q_64_U:
6458 CHECK_REG_PAIR(r3);
6459 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
6460 gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
6461 break;
6462 case OPC2_32_RR1_MUL_Q_32_LL:
6463 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
6464 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
6465 gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
6466 break;
6467 case OPC2_32_RR1_MUL_Q_32_UU:
6468 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
6469 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
6470 gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
6471 break;
6472 case OPC2_32_RR1_MULR_Q_32_L:
6473 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
6474 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
6475 gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
6476 break;
6477 case OPC2_32_RR1_MULR_Q_32_U:
6478 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
6479 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
6480 gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
6481 break;
6482 default:
6483 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6484 }
6485 }
6486
6487 /* RR2 format */
decode_rr2_mul(DisasContext * ctx)6488 static void decode_rr2_mul(DisasContext *ctx)
6489 {
6490 uint32_t op2;
6491 int r1, r2, r3;
6492
6493 op2 = MASK_OP_RR2_OP2(ctx->opcode);
6494 r1 = MASK_OP_RR2_S1(ctx->opcode);
6495 r2 = MASK_OP_RR2_S2(ctx->opcode);
6496 r3 = MASK_OP_RR2_D(ctx->opcode);
6497 switch (op2) {
6498 case OPC2_32_RR2_MUL_32:
6499 gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
6500 break;
6501 case OPC2_32_RR2_MUL_64:
6502 CHECK_REG_PAIR(r3);
6503 gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6504 cpu_gpr_d[r2]);
6505 break;
6506 case OPC2_32_RR2_MULS_32:
6507 gen_helper_mul_ssov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
6508 cpu_gpr_d[r2]);
6509 break;
6510 case OPC2_32_RR2_MUL_U_64:
6511 CHECK_REG_PAIR(r3);
6512 gen_mul_i64u(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
6513 cpu_gpr_d[r2]);
6514 break;
6515 case OPC2_32_RR2_MULS_U_32:
6516 gen_helper_mul_suov(cpu_gpr_d[r3], tcg_env, cpu_gpr_d[r1],
6517 cpu_gpr_d[r2]);
6518 break;
6519 default:
6520 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6521 }
6522 }
6523
6524 /* RRPW format */
decode_rrpw_extract_insert(DisasContext * ctx)6525 static void decode_rrpw_extract_insert(DisasContext *ctx)
6526 {
6527 uint32_t op2;
6528 int r1, r2, r3;
6529 int32_t pos, width;
6530 TCGv temp;
6531
6532 op2 = MASK_OP_RRPW_OP2(ctx->opcode);
6533 r1 = MASK_OP_RRPW_S1(ctx->opcode);
6534 r2 = MASK_OP_RRPW_S2(ctx->opcode);
6535 r3 = MASK_OP_RRPW_D(ctx->opcode);
6536 pos = MASK_OP_RRPW_POS(ctx->opcode);
6537 width = MASK_OP_RRPW_WIDTH(ctx->opcode);
6538
6539 switch (op2) {
6540 case OPC2_32_RRPW_EXTR:
6541 if (width == 0) {
6542 tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
6543 } else if (pos + width <= 32) {
6544 tcg_gen_sextract_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos, width);
6545 }
6546 break;
6547 case OPC2_32_RRPW_EXTR_U:
6548 if (width == 0) {
6549 tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
6550 } else {
6551 tcg_gen_extract_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos, width);
6552 }
6553 break;
6554 case OPC2_32_RRPW_IMASK:
6555 CHECK_REG_PAIR(r3);
6556
6557 if (pos + width <= 32) {
6558 temp = tcg_temp_new();
6559 tcg_gen_movi_tl(temp, ((1u << width) - 1) << pos);
6560 tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], pos);
6561 tcg_gen_mov_tl(cpu_gpr_d[r3 + 1], temp);
6562 }
6563
6564 break;
6565 case OPC2_32_RRPW_INSERT:
6566 /* tcg_gen_deposit_tl() does not handle the case of width = 0 */
6567 if (width == 0) {
6568 tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
6569 } else if (pos + width <= 32) {
6570 tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
6571 pos, width);
6572 }
6573 break;
6574 default:
6575 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6576 }
6577 }
6578
6579 /* RRR format */
decode_rrr_cond_select(DisasContext * ctx)6580 static void decode_rrr_cond_select(DisasContext *ctx)
6581 {
6582 uint32_t op2;
6583 int r1, r2, r3, r4;
6584 TCGv temp;
6585
6586 op2 = MASK_OP_RRR_OP2(ctx->opcode);
6587 r1 = MASK_OP_RRR_S1(ctx->opcode);
6588 r2 = MASK_OP_RRR_S2(ctx->opcode);
6589 r3 = MASK_OP_RRR_S3(ctx->opcode);
6590 r4 = MASK_OP_RRR_D(ctx->opcode);
6591
6592 switch (op2) {
6593 case OPC2_32_RRR_CADD:
6594 gen_cond_add(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
6595 cpu_gpr_d[r4], cpu_gpr_d[r3]);
6596 break;
6597 case OPC2_32_RRR_CADDN:
6598 gen_cond_add(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
6599 cpu_gpr_d[r3]);
6600 break;
6601 case OPC2_32_RRR_CSUB:
6602 gen_cond_sub(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
6603 cpu_gpr_d[r3]);
6604 break;
6605 case OPC2_32_RRR_CSUBN:
6606 gen_cond_sub(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
6607 cpu_gpr_d[r3]);
6608 break;
6609 case OPC2_32_RRR_SEL:
6610 temp = tcg_constant_i32(0);
6611 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
6612 cpu_gpr_d[r1], cpu_gpr_d[r2]);
6613 break;
6614 case OPC2_32_RRR_SELN:
6615 temp = tcg_constant_i32(0);
6616 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
6617 cpu_gpr_d[r1], cpu_gpr_d[r2]);
6618 break;
6619 default:
6620 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6621 }
6622 }
6623
decode_rrr_divide(DisasContext * ctx)6624 static void decode_rrr_divide(DisasContext *ctx)
6625 {
6626 uint32_t op2;
6627
6628 int r1, r2, r3, r4;
6629
6630 op2 = MASK_OP_RRR_OP2(ctx->opcode);
6631 r1 = MASK_OP_RRR_S1(ctx->opcode);
6632 r2 = MASK_OP_RRR_S2(ctx->opcode);
6633 r3 = MASK_OP_RRR_S3(ctx->opcode);
6634 r4 = MASK_OP_RRR_D(ctx->opcode);
6635
6636 switch (op2) {
6637 case OPC2_32_RRR_DVADJ:
6638 CHECK_REG_PAIR(r3);
6639 CHECK_REG_PAIR(r4);
6640 GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6641 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6642 break;
6643 case OPC2_32_RRR_DVSTEP:
6644 CHECK_REG_PAIR(r3);
6645 CHECK_REG_PAIR(r4);
6646 GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6647 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6648 break;
6649 case OPC2_32_RRR_DVSTEP_U:
6650 CHECK_REG_PAIR(r3);
6651 CHECK_REG_PAIR(r4);
6652 GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6653 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6654 break;
6655 case OPC2_32_RRR_IXMAX:
6656 CHECK_REG_PAIR(r3);
6657 CHECK_REG_PAIR(r4);
6658 GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6659 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6660 break;
6661 case OPC2_32_RRR_IXMAX_U:
6662 CHECK_REG_PAIR(r3);
6663 CHECK_REG_PAIR(r4);
6664 GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6665 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6666 break;
6667 case OPC2_32_RRR_IXMIN:
6668 CHECK_REG_PAIR(r3);
6669 CHECK_REG_PAIR(r4);
6670 GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6671 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6672 break;
6673 case OPC2_32_RRR_IXMIN_U:
6674 CHECK_REG_PAIR(r3);
6675 CHECK_REG_PAIR(r4);
6676 GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6677 cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6678 break;
6679 case OPC2_32_RRR_PACK:
6680 CHECK_REG_PAIR(r3);
6681 gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
6682 cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
6683 break;
6684 case OPC2_32_RRR_CRCN:
6685 if (has_feature(ctx, TRICORE_FEATURE_162)) {
6686 gen_helper_crcn(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2],
6687 cpu_gpr_d[r3]);
6688 } else {
6689 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6690 }
6691 break;
6692 case OPC2_32_RRR_ADD_F:
6693 gen_helper_fadd(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
6694 break;
6695 case OPC2_32_RRR_SUB_F:
6696 gen_helper_fsub(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
6697 break;
6698 case OPC2_32_RRR_MADD_F:
6699 gen_helper_fmadd(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6700 cpu_gpr_d[r2], cpu_gpr_d[r3]);
6701 break;
6702 case OPC2_32_RRR_MSUB_F:
6703 gen_helper_fmsub(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6704 cpu_gpr_d[r2], cpu_gpr_d[r3]);
6705 break;
6706 default:
6707 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6708 }
6709 }
6710
6711 /* RRR2 format */
decode_rrr2_madd(DisasContext * ctx)6712 static void decode_rrr2_madd(DisasContext *ctx)
6713 {
6714 uint32_t op2;
6715 uint32_t r1, r2, r3, r4;
6716
6717 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
6718 r1 = MASK_OP_RRR2_S1(ctx->opcode);
6719 r2 = MASK_OP_RRR2_S2(ctx->opcode);
6720 r3 = MASK_OP_RRR2_S3(ctx->opcode);
6721 r4 = MASK_OP_RRR2_D(ctx->opcode);
6722 switch (op2) {
6723 case OPC2_32_RRR2_MADD_32:
6724 gen_madd32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
6725 cpu_gpr_d[r2]);
6726 break;
6727 case OPC2_32_RRR2_MADD_64:
6728 CHECK_REG_PAIR(r4);
6729 CHECK_REG_PAIR(r3);
6730 gen_madd64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6731 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6732 break;
6733 case OPC2_32_RRR2_MADDS_32:
6734 gen_helper_madd32_ssov(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6735 cpu_gpr_d[r3], cpu_gpr_d[r2]);
6736 break;
6737 case OPC2_32_RRR2_MADDS_64:
6738 CHECK_REG_PAIR(r4);
6739 CHECK_REG_PAIR(r3);
6740 gen_madds_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6741 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6742 break;
6743 case OPC2_32_RRR2_MADD_U_64:
6744 CHECK_REG_PAIR(r4);
6745 CHECK_REG_PAIR(r3);
6746 gen_maddu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6747 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6748 break;
6749 case OPC2_32_RRR2_MADDS_U_32:
6750 gen_helper_madd32_suov(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6751 cpu_gpr_d[r3], cpu_gpr_d[r2]);
6752 break;
6753 case OPC2_32_RRR2_MADDS_U_64:
6754 CHECK_REG_PAIR(r4);
6755 CHECK_REG_PAIR(r3);
6756 gen_maddsu_64(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 default:
6760 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6761 }
6762 }
6763
decode_rrr2_msub(DisasContext * ctx)6764 static void decode_rrr2_msub(DisasContext *ctx)
6765 {
6766 uint32_t op2;
6767 uint32_t r1, r2, r3, r4;
6768
6769 op2 = MASK_OP_RRR2_OP2(ctx->opcode);
6770 r1 = MASK_OP_RRR2_S1(ctx->opcode);
6771 r2 = MASK_OP_RRR2_S2(ctx->opcode);
6772 r3 = MASK_OP_RRR2_S3(ctx->opcode);
6773 r4 = MASK_OP_RRR2_D(ctx->opcode);
6774
6775 switch (op2) {
6776 case OPC2_32_RRR2_MSUB_32:
6777 gen_msub32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3],
6778 cpu_gpr_d[r2]);
6779 break;
6780 case OPC2_32_RRR2_MSUB_64:
6781 CHECK_REG_PAIR(r4);
6782 CHECK_REG_PAIR(r3);
6783 gen_msub64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6784 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6785 break;
6786 case OPC2_32_RRR2_MSUBS_32:
6787 gen_helper_msub32_ssov(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6788 cpu_gpr_d[r3], cpu_gpr_d[r2]);
6789 break;
6790 case OPC2_32_RRR2_MSUBS_64:
6791 CHECK_REG_PAIR(r4);
6792 CHECK_REG_PAIR(r3);
6793 gen_msubs_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6794 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6795 break;
6796 case OPC2_32_RRR2_MSUB_U_64:
6797 CHECK_REG_PAIR(r4);
6798 CHECK_REG_PAIR(r3);
6799 gen_msubu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6800 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6801 break;
6802 case OPC2_32_RRR2_MSUBS_U_32:
6803 gen_helper_msub32_suov(cpu_gpr_d[r4], tcg_env, cpu_gpr_d[r1],
6804 cpu_gpr_d[r3], cpu_gpr_d[r2]);
6805 break;
6806 case OPC2_32_RRR2_MSUBS_U_64:
6807 CHECK_REG_PAIR(r4);
6808 CHECK_REG_PAIR(r3);
6809 gen_msubsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
6810 cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
6811 break;
6812 default:
6813 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6814 }
6815 }
6816
6817 /* RRR1 format */
decode_rrr1_madd(DisasContext * ctx)6818 static void decode_rrr1_madd(DisasContext *ctx)
6819 {
6820 uint32_t op2;
6821 uint32_t r1, r2, r3, r4, n;
6822
6823 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
6824 r1 = MASK_OP_RRR1_S1(ctx->opcode);
6825 r2 = MASK_OP_RRR1_S2(ctx->opcode);
6826 r3 = MASK_OP_RRR1_S3(ctx->opcode);
6827 r4 = MASK_OP_RRR1_D(ctx->opcode);
6828 n = MASK_OP_RRR1_N(ctx->opcode);
6829
6830 switch (op2) {
6831 case OPC2_32_RRR1_MADD_H_LL:
6832 CHECK_REG_PAIR(r4);
6833 CHECK_REG_PAIR(r3);
6834 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6835 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
6836 break;
6837 case OPC2_32_RRR1_MADD_H_LU:
6838 CHECK_REG_PAIR(r4);
6839 CHECK_REG_PAIR(r3);
6840 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6841 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
6842 break;
6843 case OPC2_32_RRR1_MADD_H_UL:
6844 CHECK_REG_PAIR(r4);
6845 CHECK_REG_PAIR(r3);
6846 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6847 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
6848 break;
6849 case OPC2_32_RRR1_MADD_H_UU:
6850 CHECK_REG_PAIR(r4);
6851 CHECK_REG_PAIR(r3);
6852 gen_madd_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6853 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
6854 break;
6855 case OPC2_32_RRR1_MADDS_H_LL:
6856 CHECK_REG_PAIR(r4);
6857 CHECK_REG_PAIR(r3);
6858 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6859 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
6860 break;
6861 case OPC2_32_RRR1_MADDS_H_LU:
6862 CHECK_REG_PAIR(r4);
6863 CHECK_REG_PAIR(r3);
6864 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6865 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
6866 break;
6867 case OPC2_32_RRR1_MADDS_H_UL:
6868 CHECK_REG_PAIR(r4);
6869 CHECK_REG_PAIR(r3);
6870 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6871 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
6872 break;
6873 case OPC2_32_RRR1_MADDS_H_UU:
6874 CHECK_REG_PAIR(r4);
6875 CHECK_REG_PAIR(r3);
6876 gen_madds_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6877 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
6878 break;
6879 case OPC2_32_RRR1_MADDM_H_LL:
6880 CHECK_REG_PAIR(r4);
6881 CHECK_REG_PAIR(r3);
6882 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6883 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
6884 break;
6885 case OPC2_32_RRR1_MADDM_H_LU:
6886 CHECK_REG_PAIR(r4);
6887 CHECK_REG_PAIR(r3);
6888 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6889 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
6890 break;
6891 case OPC2_32_RRR1_MADDM_H_UL:
6892 CHECK_REG_PAIR(r4);
6893 CHECK_REG_PAIR(r3);
6894 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6895 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
6896 break;
6897 case OPC2_32_RRR1_MADDM_H_UU:
6898 CHECK_REG_PAIR(r4);
6899 CHECK_REG_PAIR(r3);
6900 gen_maddm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6901 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
6902 break;
6903 case OPC2_32_RRR1_MADDMS_H_LL:
6904 CHECK_REG_PAIR(r4);
6905 CHECK_REG_PAIR(r3);
6906 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6907 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
6908 break;
6909 case OPC2_32_RRR1_MADDMS_H_LU:
6910 CHECK_REG_PAIR(r4);
6911 CHECK_REG_PAIR(r3);
6912 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6913 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
6914 break;
6915 case OPC2_32_RRR1_MADDMS_H_UL:
6916 CHECK_REG_PAIR(r4);
6917 CHECK_REG_PAIR(r3);
6918 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6919 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
6920 break;
6921 case OPC2_32_RRR1_MADDMS_H_UU:
6922 CHECK_REG_PAIR(r4);
6923 CHECK_REG_PAIR(r3);
6924 gen_maddms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6925 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
6926 break;
6927 case OPC2_32_RRR1_MADDR_H_LL:
6928 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6929 cpu_gpr_d[r2], n, MODE_LL);
6930 break;
6931 case OPC2_32_RRR1_MADDR_H_LU:
6932 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6933 cpu_gpr_d[r2], n, MODE_LU);
6934 break;
6935 case OPC2_32_RRR1_MADDR_H_UL:
6936 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6937 cpu_gpr_d[r2], n, MODE_UL);
6938 break;
6939 case OPC2_32_RRR1_MADDR_H_UU:
6940 gen_maddr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6941 cpu_gpr_d[r2], n, MODE_UU);
6942 break;
6943 case OPC2_32_RRR1_MADDRS_H_LL:
6944 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6945 cpu_gpr_d[r2], n, MODE_LL);
6946 break;
6947 case OPC2_32_RRR1_MADDRS_H_LU:
6948 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6949 cpu_gpr_d[r2], n, MODE_LU);
6950 break;
6951 case OPC2_32_RRR1_MADDRS_H_UL:
6952 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6953 cpu_gpr_d[r2], n, MODE_UL);
6954 break;
6955 case OPC2_32_RRR1_MADDRS_H_UU:
6956 gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6957 cpu_gpr_d[r2], n, MODE_UU);
6958 break;
6959 default:
6960 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
6961 }
6962 }
6963
decode_rrr1_maddq_h(DisasContext * ctx)6964 static void decode_rrr1_maddq_h(DisasContext *ctx)
6965 {
6966 uint32_t op2;
6967 uint32_t r1, r2, r3, r4, n;
6968 TCGv temp, temp2;
6969
6970 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
6971 r1 = MASK_OP_RRR1_S1(ctx->opcode);
6972 r2 = MASK_OP_RRR1_S2(ctx->opcode);
6973 r3 = MASK_OP_RRR1_S3(ctx->opcode);
6974 r4 = MASK_OP_RRR1_D(ctx->opcode);
6975 n = MASK_OP_RRR1_N(ctx->opcode);
6976
6977 temp = tcg_temp_new();
6978 temp2 = tcg_temp_new();
6979
6980 switch (op2) {
6981 case OPC2_32_RRR1_MADD_Q_32:
6982 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6983 cpu_gpr_d[r2], n, 32);
6984 break;
6985 case OPC2_32_RRR1_MADD_Q_64:
6986 CHECK_REG_PAIR(r4);
6987 CHECK_REG_PAIR(r3);
6988 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
6989 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
6990 n);
6991 break;
6992 case OPC2_32_RRR1_MADD_Q_32_L:
6993 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
6994 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
6995 temp, n, 16);
6996 break;
6997 case OPC2_32_RRR1_MADD_Q_64_L:
6998 CHECK_REG_PAIR(r4);
6999 CHECK_REG_PAIR(r3);
7000 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7001 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7002 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7003 n);
7004 break;
7005 case OPC2_32_RRR1_MADD_Q_32_U:
7006 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7007 gen_madd32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7008 temp, n, 16);
7009 break;
7010 case OPC2_32_RRR1_MADD_Q_64_U:
7011 CHECK_REG_PAIR(r4);
7012 CHECK_REG_PAIR(r3);
7013 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7014 gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7015 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7016 n);
7017 break;
7018 case OPC2_32_RRR1_MADD_Q_32_LL:
7019 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7020 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7021 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7022 break;
7023 case OPC2_32_RRR1_MADD_Q_64_LL:
7024 CHECK_REG_PAIR(r4);
7025 CHECK_REG_PAIR(r3);
7026 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7027 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7028 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7029 cpu_gpr_d[r3+1], temp, temp2, n);
7030 break;
7031 case OPC2_32_RRR1_MADD_Q_32_UU:
7032 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7033 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7034 gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7035 break;
7036 case OPC2_32_RRR1_MADD_Q_64_UU:
7037 CHECK_REG_PAIR(r4);
7038 CHECK_REG_PAIR(r3);
7039 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7040 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7041 gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7042 cpu_gpr_d[r3+1], temp, temp2, n);
7043 break;
7044 case OPC2_32_RRR1_MADDS_Q_32:
7045 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7046 cpu_gpr_d[r2], n, 32);
7047 break;
7048 case OPC2_32_RRR1_MADDS_Q_64:
7049 CHECK_REG_PAIR(r4);
7050 CHECK_REG_PAIR(r3);
7051 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7052 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7053 n);
7054 break;
7055 case OPC2_32_RRR1_MADDS_Q_32_L:
7056 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7057 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7058 temp, n, 16);
7059 break;
7060 case OPC2_32_RRR1_MADDS_Q_64_L:
7061 CHECK_REG_PAIR(r4);
7062 CHECK_REG_PAIR(r3);
7063 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7064 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7065 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7066 n);
7067 break;
7068 case OPC2_32_RRR1_MADDS_Q_32_U:
7069 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7070 gen_madds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7071 temp, n, 16);
7072 break;
7073 case OPC2_32_RRR1_MADDS_Q_64_U:
7074 CHECK_REG_PAIR(r4);
7075 CHECK_REG_PAIR(r3);
7076 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7077 gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7078 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7079 n);
7080 break;
7081 case OPC2_32_RRR1_MADDS_Q_32_LL:
7082 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7083 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7084 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7085 break;
7086 case OPC2_32_RRR1_MADDS_Q_64_LL:
7087 CHECK_REG_PAIR(r4);
7088 CHECK_REG_PAIR(r3);
7089 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7090 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7091 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7092 cpu_gpr_d[r3+1], temp, temp2, n);
7093 break;
7094 case OPC2_32_RRR1_MADDS_Q_32_UU:
7095 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7096 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7097 gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7098 break;
7099 case OPC2_32_RRR1_MADDS_Q_64_UU:
7100 CHECK_REG_PAIR(r4);
7101 CHECK_REG_PAIR(r3);
7102 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7103 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7104 gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7105 cpu_gpr_d[r3+1], temp, temp2, n);
7106 break;
7107 case OPC2_32_RRR1_MADDR_H_64_UL:
7108 CHECK_REG_PAIR(r3);
7109 gen_maddr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7110 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7111 break;
7112 case OPC2_32_RRR1_MADDRS_H_64_UL:
7113 CHECK_REG_PAIR(r3);
7114 gen_maddr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7115 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7116 break;
7117 case OPC2_32_RRR1_MADDR_Q_32_LL:
7118 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7119 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7120 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7121 break;
7122 case OPC2_32_RRR1_MADDR_Q_32_UU:
7123 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7124 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7125 gen_maddr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7126 break;
7127 case OPC2_32_RRR1_MADDRS_Q_32_LL:
7128 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7129 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7130 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7131 break;
7132 case OPC2_32_RRR1_MADDRS_Q_32_UU:
7133 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7134 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7135 gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7136 break;
7137 default:
7138 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7139 }
7140 }
7141
decode_rrr1_maddsu_h(DisasContext * ctx)7142 static void decode_rrr1_maddsu_h(DisasContext *ctx)
7143 {
7144 uint32_t op2;
7145 uint32_t r1, r2, r3, r4, n;
7146
7147 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7148 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7149 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7150 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7151 r4 = MASK_OP_RRR1_D(ctx->opcode);
7152 n = MASK_OP_RRR1_N(ctx->opcode);
7153
7154 switch (op2) {
7155 case OPC2_32_RRR1_MADDSU_H_32_LL:
7156 CHECK_REG_PAIR(r4);
7157 CHECK_REG_PAIR(r3);
7158 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7159 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7160 break;
7161 case OPC2_32_RRR1_MADDSU_H_32_LU:
7162 CHECK_REG_PAIR(r4);
7163 CHECK_REG_PAIR(r3);
7164 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7165 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7166 break;
7167 case OPC2_32_RRR1_MADDSU_H_32_UL:
7168 CHECK_REG_PAIR(r4);
7169 CHECK_REG_PAIR(r3);
7170 gen_maddsu_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7171 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7172 break;
7173 case OPC2_32_RRR1_MADDSU_H_32_UU:
7174 CHECK_REG_PAIR(r4);
7175 CHECK_REG_PAIR(r3);
7176 gen_maddsu_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], n, MODE_UU);
7178 break;
7179 case OPC2_32_RRR1_MADDSUS_H_32_LL:
7180 CHECK_REG_PAIR(r4);
7181 CHECK_REG_PAIR(r3);
7182 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7183 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7184 n, MODE_LL);
7185 break;
7186 case OPC2_32_RRR1_MADDSUS_H_32_LU:
7187 CHECK_REG_PAIR(r4);
7188 CHECK_REG_PAIR(r3);
7189 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7190 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7191 n, MODE_LU);
7192 break;
7193 case OPC2_32_RRR1_MADDSUS_H_32_UL:
7194 CHECK_REG_PAIR(r4);
7195 CHECK_REG_PAIR(r3);
7196 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7197 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7198 n, MODE_UL);
7199 break;
7200 case OPC2_32_RRR1_MADDSUS_H_32_UU:
7201 CHECK_REG_PAIR(r4);
7202 CHECK_REG_PAIR(r3);
7203 gen_maddsus_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7204 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7205 n, MODE_UU);
7206 break;
7207 case OPC2_32_RRR1_MADDSUM_H_64_LL:
7208 CHECK_REG_PAIR(r4);
7209 CHECK_REG_PAIR(r3);
7210 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7211 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7212 n, MODE_LL);
7213 break;
7214 case OPC2_32_RRR1_MADDSUM_H_64_LU:
7215 CHECK_REG_PAIR(r4);
7216 CHECK_REG_PAIR(r3);
7217 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7218 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7219 n, MODE_LU);
7220 break;
7221 case OPC2_32_RRR1_MADDSUM_H_64_UL:
7222 CHECK_REG_PAIR(r4);
7223 CHECK_REG_PAIR(r3);
7224 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7225 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7226 n, MODE_UL);
7227 break;
7228 case OPC2_32_RRR1_MADDSUM_H_64_UU:
7229 CHECK_REG_PAIR(r4);
7230 CHECK_REG_PAIR(r3);
7231 gen_maddsum_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7232 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7233 n, MODE_UU);
7234 break;
7235 case OPC2_32_RRR1_MADDSUMS_H_64_LL:
7236 CHECK_REG_PAIR(r4);
7237 CHECK_REG_PAIR(r3);
7238 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7239 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7240 n, MODE_LL);
7241 break;
7242 case OPC2_32_RRR1_MADDSUMS_H_64_LU:
7243 CHECK_REG_PAIR(r4);
7244 CHECK_REG_PAIR(r3);
7245 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7246 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7247 n, MODE_LU);
7248 break;
7249 case OPC2_32_RRR1_MADDSUMS_H_64_UL:
7250 CHECK_REG_PAIR(r4);
7251 CHECK_REG_PAIR(r3);
7252 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7253 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7254 n, MODE_UL);
7255 break;
7256 case OPC2_32_RRR1_MADDSUMS_H_64_UU:
7257 CHECK_REG_PAIR(r4);
7258 CHECK_REG_PAIR(r3);
7259 gen_maddsums_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7260 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7261 n, MODE_UU);
7262 break;
7263 case OPC2_32_RRR1_MADDSUR_H_16_LL:
7264 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7265 cpu_gpr_d[r2], n, MODE_LL);
7266 break;
7267 case OPC2_32_RRR1_MADDSUR_H_16_LU:
7268 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7269 cpu_gpr_d[r2], n, MODE_LU);
7270 break;
7271 case OPC2_32_RRR1_MADDSUR_H_16_UL:
7272 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7273 cpu_gpr_d[r2], n, MODE_UL);
7274 break;
7275 case OPC2_32_RRR1_MADDSUR_H_16_UU:
7276 gen_maddsur32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7277 cpu_gpr_d[r2], n, MODE_UU);
7278 break;
7279 case OPC2_32_RRR1_MADDSURS_H_16_LL:
7280 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7281 cpu_gpr_d[r2], n, MODE_LL);
7282 break;
7283 case OPC2_32_RRR1_MADDSURS_H_16_LU:
7284 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7285 cpu_gpr_d[r2], n, MODE_LU);
7286 break;
7287 case OPC2_32_RRR1_MADDSURS_H_16_UL:
7288 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7289 cpu_gpr_d[r2], n, MODE_UL);
7290 break;
7291 case OPC2_32_RRR1_MADDSURS_H_16_UU:
7292 gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7293 cpu_gpr_d[r2], n, MODE_UU);
7294 break;
7295 default:
7296 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7297 }
7298 }
7299
decode_rrr1_msub(DisasContext * ctx)7300 static void decode_rrr1_msub(DisasContext *ctx)
7301 {
7302 uint32_t op2;
7303 uint32_t r1, r2, r3, r4, n;
7304
7305 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7306 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7307 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7308 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7309 r4 = MASK_OP_RRR1_D(ctx->opcode);
7310 n = MASK_OP_RRR1_N(ctx->opcode);
7311
7312 switch (op2) {
7313 case OPC2_32_RRR1_MSUB_H_LL:
7314 CHECK_REG_PAIR(r4);
7315 CHECK_REG_PAIR(r3);
7316 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7317 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7318 break;
7319 case OPC2_32_RRR1_MSUB_H_LU:
7320 CHECK_REG_PAIR(r4);
7321 CHECK_REG_PAIR(r3);
7322 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7323 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7324 break;
7325 case OPC2_32_RRR1_MSUB_H_UL:
7326 CHECK_REG_PAIR(r4);
7327 CHECK_REG_PAIR(r3);
7328 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7329 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7330 break;
7331 case OPC2_32_RRR1_MSUB_H_UU:
7332 CHECK_REG_PAIR(r4);
7333 CHECK_REG_PAIR(r3);
7334 gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7335 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7336 break;
7337 case OPC2_32_RRR1_MSUBS_H_LL:
7338 CHECK_REG_PAIR(r4);
7339 CHECK_REG_PAIR(r3);
7340 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7341 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7342 break;
7343 case OPC2_32_RRR1_MSUBS_H_LU:
7344 CHECK_REG_PAIR(r4);
7345 CHECK_REG_PAIR(r3);
7346 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7347 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7348 break;
7349 case OPC2_32_RRR1_MSUBS_H_UL:
7350 CHECK_REG_PAIR(r4);
7351 CHECK_REG_PAIR(r3);
7352 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7353 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7354 break;
7355 case OPC2_32_RRR1_MSUBS_H_UU:
7356 CHECK_REG_PAIR(r4);
7357 CHECK_REG_PAIR(r3);
7358 gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7359 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7360 break;
7361 case OPC2_32_RRR1_MSUBM_H_LL:
7362 CHECK_REG_PAIR(r4);
7363 CHECK_REG_PAIR(r3);
7364 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7365 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7366 break;
7367 case OPC2_32_RRR1_MSUBM_H_LU:
7368 CHECK_REG_PAIR(r4);
7369 CHECK_REG_PAIR(r3);
7370 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7371 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7372 break;
7373 case OPC2_32_RRR1_MSUBM_H_UL:
7374 CHECK_REG_PAIR(r4);
7375 CHECK_REG_PAIR(r3);
7376 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7377 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7378 break;
7379 case OPC2_32_RRR1_MSUBM_H_UU:
7380 CHECK_REG_PAIR(r4);
7381 CHECK_REG_PAIR(r3);
7382 gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7383 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7384 break;
7385 case OPC2_32_RRR1_MSUBMS_H_LL:
7386 CHECK_REG_PAIR(r4);
7387 CHECK_REG_PAIR(r3);
7388 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7389 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7390 break;
7391 case OPC2_32_RRR1_MSUBMS_H_LU:
7392 CHECK_REG_PAIR(r4);
7393 CHECK_REG_PAIR(r3);
7394 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7395 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7396 break;
7397 case OPC2_32_RRR1_MSUBMS_H_UL:
7398 CHECK_REG_PAIR(r4);
7399 CHECK_REG_PAIR(r3);
7400 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7401 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7402 break;
7403 case OPC2_32_RRR1_MSUBMS_H_UU:
7404 CHECK_REG_PAIR(r4);
7405 CHECK_REG_PAIR(r3);
7406 gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7407 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
7408 break;
7409 case OPC2_32_RRR1_MSUBR_H_LL:
7410 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7411 cpu_gpr_d[r2], n, MODE_LL);
7412 break;
7413 case OPC2_32_RRR1_MSUBR_H_LU:
7414 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7415 cpu_gpr_d[r2], n, MODE_LU);
7416 break;
7417 case OPC2_32_RRR1_MSUBR_H_UL:
7418 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7419 cpu_gpr_d[r2], n, MODE_UL);
7420 break;
7421 case OPC2_32_RRR1_MSUBR_H_UU:
7422 gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7423 cpu_gpr_d[r2], n, MODE_UU);
7424 break;
7425 case OPC2_32_RRR1_MSUBRS_H_LL:
7426 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7427 cpu_gpr_d[r2], n, MODE_LL);
7428 break;
7429 case OPC2_32_RRR1_MSUBRS_H_LU:
7430 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7431 cpu_gpr_d[r2], n, MODE_LU);
7432 break;
7433 case OPC2_32_RRR1_MSUBRS_H_UL:
7434 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7435 cpu_gpr_d[r2], n, MODE_UL);
7436 break;
7437 case OPC2_32_RRR1_MSUBRS_H_UU:
7438 gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7439 cpu_gpr_d[r2], n, MODE_UU);
7440 break;
7441 default:
7442 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7443 }
7444 }
7445
decode_rrr1_msubq_h(DisasContext * ctx)7446 static void decode_rrr1_msubq_h(DisasContext *ctx)
7447 {
7448 uint32_t op2;
7449 uint32_t r1, r2, r3, r4, n;
7450 TCGv temp, temp2;
7451
7452 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7453 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7454 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7455 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7456 r4 = MASK_OP_RRR1_D(ctx->opcode);
7457 n = MASK_OP_RRR1_N(ctx->opcode);
7458
7459 temp = tcg_temp_new();
7460 temp2 = tcg_temp_new();
7461
7462 switch (op2) {
7463 case OPC2_32_RRR1_MSUB_Q_32:
7464 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7465 cpu_gpr_d[r2], n, 32);
7466 break;
7467 case OPC2_32_RRR1_MSUB_Q_64:
7468 CHECK_REG_PAIR(r4);
7469 CHECK_REG_PAIR(r3);
7470 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7471 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7472 n);
7473 break;
7474 case OPC2_32_RRR1_MSUB_Q_32_L:
7475 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7476 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7477 temp, n, 16);
7478 break;
7479 case OPC2_32_RRR1_MSUB_Q_64_L:
7480 CHECK_REG_PAIR(r4);
7481 CHECK_REG_PAIR(r3);
7482 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7483 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7484 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7485 n);
7486 break;
7487 case OPC2_32_RRR1_MSUB_Q_32_U:
7488 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7489 gen_msub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7490 temp, n, 16);
7491 break;
7492 case OPC2_32_RRR1_MSUB_Q_64_U:
7493 CHECK_REG_PAIR(r4);
7494 CHECK_REG_PAIR(r3);
7495 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7496 gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7497 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7498 n);
7499 break;
7500 case OPC2_32_RRR1_MSUB_Q_32_LL:
7501 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7502 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7503 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7504 break;
7505 case OPC2_32_RRR1_MSUB_Q_64_LL:
7506 CHECK_REG_PAIR(r4);
7507 CHECK_REG_PAIR(r3);
7508 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7509 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7510 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7511 cpu_gpr_d[r3+1], temp, temp2, n);
7512 break;
7513 case OPC2_32_RRR1_MSUB_Q_32_UU:
7514 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7515 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7516 gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7517 break;
7518 case OPC2_32_RRR1_MSUB_Q_64_UU:
7519 CHECK_REG_PAIR(r4);
7520 CHECK_REG_PAIR(r3);
7521 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7522 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7523 gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7524 cpu_gpr_d[r3+1], temp, temp2, n);
7525 break;
7526 case OPC2_32_RRR1_MSUBS_Q_32:
7527 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7528 cpu_gpr_d[r2], n, 32);
7529 break;
7530 case OPC2_32_RRR1_MSUBS_Q_64:
7531 CHECK_REG_PAIR(r4);
7532 CHECK_REG_PAIR(r3);
7533 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7534 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7535 n);
7536 break;
7537 case OPC2_32_RRR1_MSUBS_Q_32_L:
7538 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7539 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7540 temp, n, 16);
7541 break;
7542 case OPC2_32_RRR1_MSUBS_Q_64_L:
7543 CHECK_REG_PAIR(r4);
7544 CHECK_REG_PAIR(r3);
7545 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
7546 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7547 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7548 n);
7549 break;
7550 case OPC2_32_RRR1_MSUBS_Q_32_U:
7551 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7552 gen_msubs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7553 temp, n, 16);
7554 break;
7555 case OPC2_32_RRR1_MSUBS_Q_64_U:
7556 CHECK_REG_PAIR(r4);
7557 CHECK_REG_PAIR(r3);
7558 tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
7559 gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7560 cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
7561 n);
7562 break;
7563 case OPC2_32_RRR1_MSUBS_Q_32_LL:
7564 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7565 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7566 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7567 break;
7568 case OPC2_32_RRR1_MSUBS_Q_64_LL:
7569 CHECK_REG_PAIR(r4);
7570 CHECK_REG_PAIR(r3);
7571 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7572 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7573 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7574 cpu_gpr_d[r3+1], temp, temp2, n);
7575 break;
7576 case OPC2_32_RRR1_MSUBS_Q_32_UU:
7577 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7578 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7579 gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7580 break;
7581 case OPC2_32_RRR1_MSUBS_Q_64_UU:
7582 CHECK_REG_PAIR(r4);
7583 CHECK_REG_PAIR(r3);
7584 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7585 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7586 gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7587 cpu_gpr_d[r3+1], temp, temp2, n);
7588 break;
7589 case OPC2_32_RRR1_MSUBR_H_64_UL:
7590 CHECK_REG_PAIR(r3);
7591 gen_msubr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7592 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7593 break;
7594 case OPC2_32_RRR1_MSUBRS_H_64_UL:
7595 CHECK_REG_PAIR(r3);
7596 gen_msubr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
7597 cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
7598 break;
7599 case OPC2_32_RRR1_MSUBR_Q_32_LL:
7600 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7601 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7602 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7603 break;
7604 case OPC2_32_RRR1_MSUBR_Q_32_UU:
7605 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7606 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7607 gen_msubr_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7608 break;
7609 case OPC2_32_RRR1_MSUBRS_Q_32_LL:
7610 tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
7611 tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
7612 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7613 break;
7614 case OPC2_32_RRR1_MSUBRS_Q_32_UU:
7615 tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
7616 tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
7617 gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
7618 break;
7619 default:
7620 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7621 }
7622 }
7623
decode_rrr1_msubad_h(DisasContext * ctx)7624 static void decode_rrr1_msubad_h(DisasContext *ctx)
7625 {
7626 uint32_t op2;
7627 uint32_t r1, r2, r3, r4, n;
7628
7629 op2 = MASK_OP_RRR1_OP2(ctx->opcode);
7630 r1 = MASK_OP_RRR1_S1(ctx->opcode);
7631 r2 = MASK_OP_RRR1_S2(ctx->opcode);
7632 r3 = MASK_OP_RRR1_S3(ctx->opcode);
7633 r4 = MASK_OP_RRR1_D(ctx->opcode);
7634 n = MASK_OP_RRR1_N(ctx->opcode);
7635
7636 switch (op2) {
7637 case OPC2_32_RRR1_MSUBAD_H_32_LL:
7638 CHECK_REG_PAIR(r4);
7639 CHECK_REG_PAIR(r3);
7640 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7641 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
7642 break;
7643 case OPC2_32_RRR1_MSUBAD_H_32_LU:
7644 CHECK_REG_PAIR(r4);
7645 CHECK_REG_PAIR(r3);
7646 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7647 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
7648 break;
7649 case OPC2_32_RRR1_MSUBAD_H_32_UL:
7650 CHECK_REG_PAIR(r4);
7651 CHECK_REG_PAIR(r3);
7652 gen_msubad_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7653 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
7654 break;
7655 case OPC2_32_RRR1_MSUBAD_H_32_UU:
7656 CHECK_REG_PAIR(r4);
7657 CHECK_REG_PAIR(r3);
7658 gen_msubad_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], n, MODE_UU);
7660 break;
7661 case OPC2_32_RRR1_MSUBADS_H_32_LL:
7662 CHECK_REG_PAIR(r4);
7663 CHECK_REG_PAIR(r3);
7664 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7665 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7666 n, MODE_LL);
7667 break;
7668 case OPC2_32_RRR1_MSUBADS_H_32_LU:
7669 CHECK_REG_PAIR(r4);
7670 CHECK_REG_PAIR(r3);
7671 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7672 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7673 n, MODE_LU);
7674 break;
7675 case OPC2_32_RRR1_MSUBADS_H_32_UL:
7676 CHECK_REG_PAIR(r4);
7677 CHECK_REG_PAIR(r3);
7678 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7679 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7680 n, MODE_UL);
7681 break;
7682 case OPC2_32_RRR1_MSUBADS_H_32_UU:
7683 CHECK_REG_PAIR(r4);
7684 CHECK_REG_PAIR(r3);
7685 gen_msubads_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7686 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7687 n, MODE_UU);
7688 break;
7689 case OPC2_32_RRR1_MSUBADM_H_64_LL:
7690 CHECK_REG_PAIR(r4);
7691 CHECK_REG_PAIR(r3);
7692 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7693 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7694 n, MODE_LL);
7695 break;
7696 case OPC2_32_RRR1_MSUBADM_H_64_LU:
7697 CHECK_REG_PAIR(r4);
7698 CHECK_REG_PAIR(r3);
7699 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7700 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7701 n, MODE_LU);
7702 break;
7703 case OPC2_32_RRR1_MSUBADM_H_64_UL:
7704 CHECK_REG_PAIR(r4);
7705 CHECK_REG_PAIR(r3);
7706 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7707 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7708 n, MODE_UL);
7709 break;
7710 case OPC2_32_RRR1_MSUBADM_H_64_UU:
7711 CHECK_REG_PAIR(r4);
7712 CHECK_REG_PAIR(r3);
7713 gen_msubadm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7714 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7715 n, MODE_UU);
7716 break;
7717 case OPC2_32_RRR1_MSUBADMS_H_64_LL:
7718 CHECK_REG_PAIR(r4);
7719 CHECK_REG_PAIR(r3);
7720 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7721 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7722 n, MODE_LL);
7723 break;
7724 case OPC2_32_RRR1_MSUBADMS_H_64_LU:
7725 CHECK_REG_PAIR(r4);
7726 CHECK_REG_PAIR(r3);
7727 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7728 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7729 n, MODE_LU);
7730 break;
7731 case OPC2_32_RRR1_MSUBADMS_H_64_UL:
7732 CHECK_REG_PAIR(r4);
7733 CHECK_REG_PAIR(r3);
7734 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7735 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7736 n, MODE_UL);
7737 break;
7738 case OPC2_32_RRR1_MSUBADMS_H_64_UU:
7739 CHECK_REG_PAIR(r4);
7740 CHECK_REG_PAIR(r3);
7741 gen_msubadms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
7742 cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
7743 n, MODE_UU);
7744 break;
7745 case OPC2_32_RRR1_MSUBADR_H_16_LL:
7746 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7747 cpu_gpr_d[r2], n, MODE_LL);
7748 break;
7749 case OPC2_32_RRR1_MSUBADR_H_16_LU:
7750 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7751 cpu_gpr_d[r2], n, MODE_LU);
7752 break;
7753 case OPC2_32_RRR1_MSUBADR_H_16_UL:
7754 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7755 cpu_gpr_d[r2], n, MODE_UL);
7756 break;
7757 case OPC2_32_RRR1_MSUBADR_H_16_UU:
7758 gen_msubadr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7759 cpu_gpr_d[r2], n, MODE_UU);
7760 break;
7761 case OPC2_32_RRR1_MSUBADRS_H_16_LL:
7762 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7763 cpu_gpr_d[r2], n, MODE_LL);
7764 break;
7765 case OPC2_32_RRR1_MSUBADRS_H_16_LU:
7766 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7767 cpu_gpr_d[r2], n, MODE_LU);
7768 break;
7769 case OPC2_32_RRR1_MSUBADRS_H_16_UL:
7770 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7771 cpu_gpr_d[r2], n, MODE_UL);
7772 break;
7773 case OPC2_32_RRR1_MSUBADRS_H_16_UU:
7774 gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
7775 cpu_gpr_d[r2], n, MODE_UU);
7776 break;
7777 default:
7778 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7779 }
7780 }
7781
7782 /* RRRR format */
decode_rrrr_extract_insert(DisasContext * ctx)7783 static void decode_rrrr_extract_insert(DisasContext *ctx)
7784 {
7785 uint32_t op2;
7786 int r1, r2, r3, r4;
7787 TCGv tmp_width, tmp_pos;
7788
7789 r1 = MASK_OP_RRRR_S1(ctx->opcode);
7790 r2 = MASK_OP_RRRR_S2(ctx->opcode);
7791 r3 = MASK_OP_RRRR_S3(ctx->opcode);
7792 r4 = MASK_OP_RRRR_D(ctx->opcode);
7793 op2 = MASK_OP_RRRR_OP2(ctx->opcode);
7794
7795 tmp_pos = tcg_temp_new();
7796 tmp_width = tcg_temp_new();
7797
7798 switch (op2) {
7799 case OPC2_32_RRRR_DEXTR:
7800 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
7801 if (r1 == r2) {
7802 tcg_gen_rotl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
7803 } else {
7804 TCGv msw = tcg_temp_new();
7805 TCGv zero = tcg_constant_tl(0);
7806 tcg_gen_shl_tl(tmp_width, cpu_gpr_d[r1], tmp_pos);
7807 tcg_gen_subfi_tl(msw, 32, tmp_pos);
7808 tcg_gen_shr_tl(msw, cpu_gpr_d[r2], msw);
7809 /*
7810 * if pos == 0, then we do cpu_gpr_d[r2] << 32, which is undefined
7811 * behaviour. So check that case here and set the low bits to zero
7812 * which effectivly returns cpu_gpr_d[r1]
7813 */
7814 tcg_gen_movcond_tl(TCG_COND_EQ, msw, tmp_pos, zero, zero, msw);
7815 tcg_gen_or_tl(cpu_gpr_d[r4], tmp_width, msw);
7816 }
7817 break;
7818 case OPC2_32_RRRR_EXTR:
7819 case OPC2_32_RRRR_EXTR_U:
7820 CHECK_REG_PAIR(r3);
7821 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
7822 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
7823 tcg_gen_add_tl(tmp_pos, tmp_pos, tmp_width);
7824 tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
7825 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
7826 tcg_gen_subfi_tl(tmp_width, 32, tmp_width);
7827 if (op2 == OPC2_32_RRRR_EXTR) {
7828 tcg_gen_sar_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
7829 } else {
7830 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], tmp_width);
7831 }
7832 break;
7833 case OPC2_32_RRRR_INSERT:
7834 CHECK_REG_PAIR(r3);
7835 tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
7836 tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
7837 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], tmp_width,
7838 tmp_pos);
7839 break;
7840 default:
7841 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7842 }
7843 }
7844
7845 /* RRRW format */
decode_rrrw_extract_insert(DisasContext * ctx)7846 static void decode_rrrw_extract_insert(DisasContext *ctx)
7847 {
7848 uint32_t op2;
7849 int r1, r2, r3, r4;
7850 int32_t width;
7851
7852 TCGv temp, temp2;
7853
7854 op2 = MASK_OP_RRRW_OP2(ctx->opcode);
7855 r1 = MASK_OP_RRRW_S1(ctx->opcode);
7856 r2 = MASK_OP_RRRW_S2(ctx->opcode);
7857 r3 = MASK_OP_RRRW_S3(ctx->opcode);
7858 r4 = MASK_OP_RRRW_D(ctx->opcode);
7859 width = MASK_OP_RRRW_WIDTH(ctx->opcode);
7860
7861 temp = tcg_temp_new();
7862
7863 switch (op2) {
7864 case OPC2_32_RRRW_EXTR:
7865 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
7866 tcg_gen_addi_tl(temp, temp, width);
7867 tcg_gen_subfi_tl(temp, 32, temp);
7868 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
7869 tcg_gen_sari_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], 32 - width);
7870 break;
7871 case OPC2_32_RRRW_EXTR_U:
7872 if (width == 0) {
7873 tcg_gen_movi_tl(cpu_gpr_d[r4], 0);
7874 } else {
7875 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
7876 tcg_gen_shr_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], temp);
7877 tcg_gen_andi_tl(cpu_gpr_d[r4], cpu_gpr_d[r4], ~0u >> (32-width));
7878 }
7879 break;
7880 case OPC2_32_RRRW_IMASK:
7881 temp2 = tcg_temp_new();
7882 CHECK_REG_PAIR(r4);
7883 tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
7884 tcg_gen_movi_tl(temp2, (1 << width) - 1);
7885 tcg_gen_shl_tl(temp2, temp2, temp);
7886 tcg_gen_shl_tl(cpu_gpr_d[r4], cpu_gpr_d[r2], temp);
7887 tcg_gen_mov_tl(cpu_gpr_d[r4+1], temp2);
7888 break;
7889 case OPC2_32_RRRW_INSERT:
7890 temp2 = tcg_temp_new();
7891
7892 tcg_gen_movi_tl(temp, width);
7893 tcg_gen_andi_tl(temp2, cpu_gpr_d[r3], 0x1f);
7894 gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], temp, temp2);
7895 break;
7896 default:
7897 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7898 }
7899 }
7900
7901 /* SYS Format*/
decode_sys_interrupts(DisasContext * ctx)7902 static void decode_sys_interrupts(DisasContext *ctx)
7903 {
7904 uint32_t op2;
7905 uint32_t r1;
7906 TCGLabel *l1;
7907 TCGv tmp;
7908
7909 op2 = MASK_OP_SYS_OP2(ctx->opcode);
7910 r1 = MASK_OP_SYS_S1D(ctx->opcode);
7911
7912 switch (op2) {
7913 case OPC2_32_SYS_DEBUG:
7914 /* raise EXCP_DEBUG */
7915 break;
7916 case OPC2_32_SYS_DISABLE:
7917 if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
7918 tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask);
7919 } else {
7920 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
7921 }
7922 break;
7923 case OPC2_32_SYS_DISABLE_D:
7924 if (has_feature(ctx, TRICORE_FEATURE_16)) {
7925 if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
7926 tcg_gen_extract_tl(cpu_gpr_d[r1], cpu_ICR,
7927 ctx->icr_ie_offset, 1);
7928 tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask);
7929 } else {
7930 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
7931 }
7932 } else {
7933 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7934 }
7935 case OPC2_32_SYS_DSYNC:
7936 break;
7937 case OPC2_32_SYS_ENABLE:
7938 if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
7939 tcg_gen_ori_tl(cpu_ICR, cpu_ICR, ctx->icr_ie_mask);
7940 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
7941 } else {
7942 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
7943 }
7944 break;
7945 case OPC2_32_SYS_ISYNC:
7946 break;
7947 case OPC2_32_SYS_NOP:
7948 break;
7949 case OPC2_32_SYS_RET:
7950 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
7951 break;
7952 case OPC2_32_SYS_FRET:
7953 gen_fret(ctx);
7954 break;
7955 case OPC2_32_SYS_RFE:
7956 gen_helper_rfe(tcg_env);
7957 ctx->base.is_jmp = DISAS_EXIT;
7958 break;
7959 case OPC2_32_SYS_RFM:
7960 if (ctx->priv == TRICORE_PRIV_SM) {
7961 tmp = tcg_temp_new();
7962 l1 = gen_new_label();
7963
7964 tcg_gen_ld32u_tl(tmp, tcg_env, offsetof(CPUTriCoreState, DBGSR));
7965 tcg_gen_andi_tl(tmp, tmp, MASK_DBGSR_DE);
7966 tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1);
7967 gen_helper_rfm(tcg_env);
7968 gen_set_label(l1);
7969 ctx->base.is_jmp = DISAS_EXIT;
7970 } else {
7971 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
7972 }
7973 break;
7974 case OPC2_32_SYS_RSLCX:
7975 gen_helper_rslcx(tcg_env);
7976 break;
7977 case OPC2_32_SYS_SVLCX:
7978 gen_helper_svlcx(tcg_env);
7979 break;
7980 case OPC2_32_SYS_RESTORE:
7981 if (has_feature(ctx, TRICORE_FEATURE_16)) {
7982 if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
7983 tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1],
7984 ctx->icr_ie_offset, 1);
7985 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
7986 } else {
7987 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
7988 }
7989 } else {
7990 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
7991 }
7992 break;
7993 case OPC2_32_SYS_TRAPSV:
7994 l1 = gen_new_label();
7995 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_SV, 0, l1);
7996 generate_trap(ctx, TRAPC_ASSERT, TIN5_SOVF);
7997 gen_set_label(l1);
7998 break;
7999 case OPC2_32_SYS_TRAPV:
8000 l1 = gen_new_label();
8001 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_V, 0, l1);
8002 generate_trap(ctx, TRAPC_ASSERT, TIN5_OVF);
8003 gen_set_label(l1);
8004 break;
8005 default:
8006 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8007 }
8008 }
8009
decode_32Bit_opc(DisasContext * ctx)8010 static void decode_32Bit_opc(DisasContext *ctx)
8011 {
8012 int op1, op2;
8013 int32_t r1, r2, r3;
8014 int32_t address, const16;
8015 int8_t b, const4;
8016 int32_t bpos;
8017 TCGv temp, temp2, temp3;
8018
8019 op1 = MASK_OP_MAJOR(ctx->opcode);
8020
8021 /* handle JNZ.T opcode only being 7 bit long */
8022 if (unlikely((op1 & 0x7f) == OPCM_32_BRN_JTT)) {
8023 op1 = OPCM_32_BRN_JTT;
8024 }
8025
8026 switch (op1) {
8027 /* ABS-format */
8028 case OPCM_32_ABS_LDW:
8029 decode_abs_ldw(ctx);
8030 break;
8031 case OPCM_32_ABS_LDB:
8032 decode_abs_ldb(ctx);
8033 break;
8034 case OPCM_32_ABS_LDMST_SWAP:
8035 decode_abs_ldst_swap(ctx);
8036 break;
8037 case OPCM_32_ABS_LDST_CONTEXT:
8038 decode_abs_ldst_context(ctx);
8039 break;
8040 case OPCM_32_ABS_STORE:
8041 decode_abs_store(ctx);
8042 break;
8043 case OPCM_32_ABS_STOREB_H:
8044 decode_abs_storeb_h(ctx);
8045 break;
8046 case OPC1_32_ABS_STOREQ:
8047 address = MASK_OP_ABS_OFF18(ctx->opcode);
8048 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8049 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
8050 temp2 = tcg_temp_new();
8051
8052 tcg_gen_shri_tl(temp2, cpu_gpr_d[r1], 16);
8053 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_LEUW);
8054 break;
8055 case OPC1_32_ABS_LD_Q:
8056 address = MASK_OP_ABS_OFF18(ctx->opcode);
8057 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8058 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
8059
8060 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
8061 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
8062 break;
8063 case OPCM_32_ABS_LEA_LHA:
8064 address = MASK_OP_ABS_OFF18(ctx->opcode);
8065 r1 = MASK_OP_ABS_S1D(ctx->opcode);
8066
8067 if (has_feature(ctx, TRICORE_FEATURE_162)) {
8068 op2 = MASK_OP_ABS_OP2(ctx->opcode);
8069 if (op2 == OPC2_32_ABS_LHA) {
8070 tcg_gen_movi_tl(cpu_gpr_a[r1], address << 14);
8071 break;
8072 }
8073 /* otherwise translate regular LEA */
8074 }
8075
8076 tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address));
8077 break;
8078 /* ABSB-format */
8079 case OPC1_32_ABSB_ST_T:
8080 address = MASK_OP_ABS_OFF18(ctx->opcode);
8081 b = MASK_OP_ABSB_B(ctx->opcode);
8082 bpos = MASK_OP_ABSB_BPOS(ctx->opcode);
8083
8084 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
8085 temp2 = tcg_temp_new();
8086
8087 tcg_gen_qemu_ld_tl(temp2, temp, ctx->mem_idx, MO_UB);
8088 tcg_gen_andi_tl(temp2, temp2, ~(0x1u << bpos));
8089 tcg_gen_ori_tl(temp2, temp2, (b << bpos));
8090 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_UB);
8091 break;
8092 /* B-format */
8093 case OPC1_32_B_CALL:
8094 case OPC1_32_B_CALLA:
8095 case OPC1_32_B_FCALL:
8096 case OPC1_32_B_FCALLA:
8097 case OPC1_32_B_J:
8098 case OPC1_32_B_JA:
8099 case OPC1_32_B_JL:
8100 case OPC1_32_B_JLA:
8101 address = MASK_OP_B_DISP24_SEXT(ctx->opcode);
8102 gen_compute_branch(ctx, op1, 0, 0, 0, address);
8103 break;
8104 /* Bit-format */
8105 case OPCM_32_BIT_ANDACC:
8106 decode_bit_andacc(ctx);
8107 break;
8108 case OPCM_32_BIT_LOGICAL_T1:
8109 decode_bit_logical_t(ctx);
8110 break;
8111 case OPCM_32_BIT_INSERT:
8112 decode_bit_insert(ctx);
8113 break;
8114 case OPCM_32_BIT_LOGICAL_T2:
8115 decode_bit_logical_t2(ctx);
8116 break;
8117 case OPCM_32_BIT_ORAND:
8118 decode_bit_orand(ctx);
8119 break;
8120 case OPCM_32_BIT_SH_LOGIC1:
8121 decode_bit_sh_logic1(ctx);
8122 break;
8123 case OPCM_32_BIT_SH_LOGIC2:
8124 decode_bit_sh_logic2(ctx);
8125 break;
8126 /* BO Format */
8127 case OPCM_32_BO_ADDRMODE_POST_PRE_BASE:
8128 decode_bo_addrmode_post_pre_base(ctx);
8129 break;
8130 case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR:
8131 decode_bo_addrmode_bitreverse_circular(ctx);
8132 break;
8133 case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE:
8134 decode_bo_addrmode_ld_post_pre_base(ctx);
8135 break;
8136 case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR:
8137 decode_bo_addrmode_ld_bitreverse_circular(ctx);
8138 break;
8139 case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE:
8140 decode_bo_addrmode_stctx_post_pre_base(ctx);
8141 break;
8142 case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR:
8143 decode_bo_addrmode_ldmst_bitreverse_circular(ctx);
8144 break;
8145 /* BOL-format */
8146 case OPC1_32_BOL_LD_A_LONGOFF:
8147 case OPC1_32_BOL_LD_W_LONGOFF:
8148 case OPC1_32_BOL_LEA_LONGOFF:
8149 case OPC1_32_BOL_ST_W_LONGOFF:
8150 case OPC1_32_BOL_ST_A_LONGOFF:
8151 case OPC1_32_BOL_LD_B_LONGOFF:
8152 case OPC1_32_BOL_LD_BU_LONGOFF:
8153 case OPC1_32_BOL_LD_H_LONGOFF:
8154 case OPC1_32_BOL_LD_HU_LONGOFF:
8155 case OPC1_32_BOL_ST_B_LONGOFF:
8156 case OPC1_32_BOL_ST_H_LONGOFF:
8157 decode_bol_opc(ctx, op1);
8158 break;
8159 /* BRC Format */
8160 case OPCM_32_BRC_EQ_NEQ:
8161 case OPCM_32_BRC_GE:
8162 case OPCM_32_BRC_JLT:
8163 case OPCM_32_BRC_JNE:
8164 const4 = MASK_OP_BRC_CONST4_SEXT(ctx->opcode);
8165 address = MASK_OP_BRC_DISP15_SEXT(ctx->opcode);
8166 r1 = MASK_OP_BRC_S1(ctx->opcode);
8167 gen_compute_branch(ctx, op1, r1, 0, const4, address);
8168 break;
8169 /* BRN Format */
8170 case OPCM_32_BRN_JTT:
8171 address = MASK_OP_BRN_DISP15_SEXT(ctx->opcode);
8172 r1 = MASK_OP_BRN_S1(ctx->opcode);
8173 gen_compute_branch(ctx, op1, r1, 0, 0, address);
8174 break;
8175 /* BRR Format */
8176 case OPCM_32_BRR_EQ_NEQ:
8177 case OPCM_32_BRR_ADDR_EQ_NEQ:
8178 case OPCM_32_BRR_GE:
8179 case OPCM_32_BRR_JLT:
8180 case OPCM_32_BRR_JNE:
8181 case OPCM_32_BRR_JNZ:
8182 case OPCM_32_BRR_LOOP:
8183 address = MASK_OP_BRR_DISP15_SEXT(ctx->opcode);
8184 r2 = MASK_OP_BRR_S2(ctx->opcode);
8185 r1 = MASK_OP_BRR_S1(ctx->opcode);
8186 gen_compute_branch(ctx, op1, r1, r2, 0, address);
8187 break;
8188 /* RC Format */
8189 case OPCM_32_RC_LOGICAL_SHIFT:
8190 decode_rc_logical_shift(ctx);
8191 break;
8192 case OPCM_32_RC_ACCUMULATOR:
8193 decode_rc_accumulator(ctx);
8194 break;
8195 case OPCM_32_RC_SERVICEROUTINE:
8196 decode_rc_serviceroutine(ctx);
8197 break;
8198 case OPCM_32_RC_MUL:
8199 decode_rc_mul(ctx);
8200 break;
8201 /* RCPW Format */
8202 case OPCM_32_RCPW_MASK_INSERT:
8203 decode_rcpw_insert(ctx);
8204 break;
8205 /* RCRR Format */
8206 case OPC1_32_RCRR_INSERT:
8207 r1 = MASK_OP_RCRR_S1(ctx->opcode);
8208 r2 = MASK_OP_RCRR_S3(ctx->opcode);
8209 r3 = MASK_OP_RCRR_D(ctx->opcode);
8210 const16 = MASK_OP_RCRR_CONST4(ctx->opcode);
8211 temp = tcg_constant_i32(const16);
8212 temp2 = tcg_temp_new(); /* width*/
8213 temp3 = tcg_temp_new(); /* pos */
8214
8215 CHECK_REG_PAIR(r2);
8216
8217 tcg_gen_andi_tl(temp2, cpu_gpr_d[r2 + 1], 0x1f);
8218 tcg_gen_andi_tl(temp3, cpu_gpr_d[r2], 0x1f);
8219
8220 gen_insert(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, temp2, temp3);
8221 break;
8222 /* RCRW Format */
8223 case OPCM_32_RCRW_MASK_INSERT:
8224 decode_rcrw_insert(ctx);
8225 break;
8226 /* RCR Format */
8227 case OPCM_32_RCR_COND_SELECT:
8228 decode_rcr_cond_select(ctx);
8229 break;
8230 case OPCM_32_RCR_MADD:
8231 decode_rcr_madd(ctx);
8232 break;
8233 case OPCM_32_RCR_MSUB:
8234 decode_rcr_msub(ctx);
8235 break;
8236 /* RLC Format */
8237 case OPC1_32_RLC_ADDI:
8238 case OPC1_32_RLC_ADDIH:
8239 case OPC1_32_RLC_ADDIH_A:
8240 case OPC1_32_RLC_MFCR:
8241 case OPC1_32_RLC_MOV:
8242 case OPC1_32_RLC_MOV_64:
8243 case OPC1_32_RLC_MOV_U:
8244 case OPC1_32_RLC_MOV_H:
8245 case OPC1_32_RLC_MOVH_A:
8246 case OPC1_32_RLC_MTCR:
8247 decode_rlc_opc(ctx, op1);
8248 break;
8249 /* RR Format */
8250 case OPCM_32_RR_ACCUMULATOR:
8251 decode_rr_accumulator(ctx);
8252 break;
8253 case OPCM_32_RR_LOGICAL_SHIFT:
8254 decode_rr_logical_shift(ctx);
8255 break;
8256 case OPCM_32_RR_ADDRESS:
8257 decode_rr_address(ctx);
8258 break;
8259 case OPCM_32_RR_IDIRECT:
8260 decode_rr_idirect(ctx);
8261 break;
8262 case OPCM_32_RR_DIVIDE:
8263 decode_rr_divide(ctx);
8264 break;
8265 /* RR1 Format */
8266 case OPCM_32_RR1_MUL:
8267 decode_rr1_mul(ctx);
8268 break;
8269 case OPCM_32_RR1_MULQ:
8270 decode_rr1_mulq(ctx);
8271 break;
8272 /* RR2 format */
8273 case OPCM_32_RR2_MUL:
8274 decode_rr2_mul(ctx);
8275 break;
8276 /* RRPW format */
8277 case OPCM_32_RRPW_EXTRACT_INSERT:
8278 decode_rrpw_extract_insert(ctx);
8279 break;
8280 case OPC1_32_RRPW_DEXTR:
8281 r1 = MASK_OP_RRPW_S1(ctx->opcode);
8282 r2 = MASK_OP_RRPW_S2(ctx->opcode);
8283 r3 = MASK_OP_RRPW_D(ctx->opcode);
8284 const16 = MASK_OP_RRPW_POS(ctx->opcode);
8285
8286 tcg_gen_extract2_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], cpu_gpr_d[r1],
8287 32 - const16);
8288 break;
8289 /* RRR Format */
8290 case OPCM_32_RRR_COND_SELECT:
8291 decode_rrr_cond_select(ctx);
8292 break;
8293 case OPCM_32_RRR_DIVIDE:
8294 decode_rrr_divide(ctx);
8295 break;
8296 /* RRR2 Format */
8297 case OPCM_32_RRR2_MADD:
8298 decode_rrr2_madd(ctx);
8299 break;
8300 case OPCM_32_RRR2_MSUB:
8301 decode_rrr2_msub(ctx);
8302 break;
8303 /* RRR1 format */
8304 case OPCM_32_RRR1_MADD:
8305 decode_rrr1_madd(ctx);
8306 break;
8307 case OPCM_32_RRR1_MADDQ_H:
8308 decode_rrr1_maddq_h(ctx);
8309 break;
8310 case OPCM_32_RRR1_MADDSU_H:
8311 decode_rrr1_maddsu_h(ctx);
8312 break;
8313 case OPCM_32_RRR1_MSUB_H:
8314 decode_rrr1_msub(ctx);
8315 break;
8316 case OPCM_32_RRR1_MSUB_Q:
8317 decode_rrr1_msubq_h(ctx);
8318 break;
8319 case OPCM_32_RRR1_MSUBAD_H:
8320 decode_rrr1_msubad_h(ctx);
8321 break;
8322 /* RRRR format */
8323 case OPCM_32_RRRR_EXTRACT_INSERT:
8324 decode_rrrr_extract_insert(ctx);
8325 break;
8326 /* RRRW format */
8327 case OPCM_32_RRRW_EXTRACT_INSERT:
8328 decode_rrrw_extract_insert(ctx);
8329 break;
8330 /* SYS format */
8331 case OPCM_32_SYS_INTERRUPTS:
8332 decode_sys_interrupts(ctx);
8333 break;
8334 case OPC1_32_SYS_RSTV:
8335 tcg_gen_movi_tl(cpu_PSW_V, 0);
8336 tcg_gen_mov_tl(cpu_PSW_SV, cpu_PSW_V);
8337 tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
8338 tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V);
8339 break;
8340 default:
8341 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
8342 }
8343 }
8344
tricore_insn_is_16bit(uint32_t insn)8345 static bool tricore_insn_is_16bit(uint32_t insn)
8346 {
8347 return (insn & 0x1) == 0;
8348 }
8349
tricore_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)8350 static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
8351 CPUState *cs)
8352 {
8353 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8354 CPUTriCoreState *env = cpu_env(cs);
8355 ctx->mem_idx = cpu_mmu_index(cs, false);
8356
8357 uint32_t tb_flags = (uint32_t)ctx->base.tb->flags;
8358 ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
8359
8360 ctx->features = env->features;
8361 if (has_feature(ctx, TRICORE_FEATURE_161)) {
8362 ctx->icr_ie_mask = R_ICR_IE_161_MASK;
8363 ctx->icr_ie_offset = R_ICR_IE_161_SHIFT;
8364 } else {
8365 ctx->icr_ie_mask = R_ICR_IE_13_MASK;
8366 ctx->icr_ie_offset = R_ICR_IE_13_SHIFT;
8367 }
8368 }
8369
tricore_tr_tb_start(DisasContextBase * db,CPUState * cpu)8370 static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8371 {
8372 }
8373
tricore_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)8374 static void tricore_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8375 {
8376 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8377
8378 tcg_gen_insn_start(ctx->base.pc_next);
8379 }
8380
insn_crosses_page(CPUTriCoreState * env,DisasContext * ctx)8381 static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx)
8382 {
8383 /*
8384 * Return true if the insn at ctx->base.pc_next might cross a page boundary.
8385 * (False positives are OK, false negatives are not.)
8386 * Our caller ensures we are only called if dc->base.pc_next is less than
8387 * 4 bytes from the page boundary, so we cross the page if the first
8388 * 16 bits indicate that this is a 32 bit insn.
8389 */
8390 uint16_t insn = translator_lduw(env, &ctx->base, ctx->base.pc_next);
8391
8392 return !tricore_insn_is_16bit(insn);
8393 }
8394
8395
tricore_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)8396 static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8397 {
8398 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8399 CPUTriCoreState *env = cpu_env(cpu);
8400 uint16_t insn_lo;
8401 bool is_16bit;
8402
8403 insn_lo = translator_lduw(env, &ctx->base, ctx->base.pc_next);
8404 is_16bit = tricore_insn_is_16bit(insn_lo);
8405 if (is_16bit) {
8406 ctx->opcode = insn_lo;
8407 ctx->pc_succ_insn = ctx->base.pc_next + 2;
8408 decode_16Bit_opc(ctx);
8409 } else {
8410 uint32_t insn_hi = translator_lduw(env, &ctx->base,
8411 ctx->base.pc_next + 2);
8412 ctx->opcode = insn_hi << 16 | insn_lo;
8413 ctx->pc_succ_insn = ctx->base.pc_next + 4;
8414 decode_32Bit_opc(ctx);
8415 }
8416 ctx->base.pc_next = ctx->pc_succ_insn;
8417
8418 if (ctx->base.is_jmp == DISAS_NEXT) {
8419 target_ulong page_start;
8420
8421 page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
8422 if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE
8423 || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3
8424 && insn_crosses_page(env, ctx))) {
8425 ctx->base.is_jmp = DISAS_TOO_MANY;
8426 }
8427 }
8428 }
8429
tricore_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)8430 static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8431 {
8432 DisasContext *ctx = container_of(dcbase, DisasContext, base);
8433
8434 switch (ctx->base.is_jmp) {
8435 case DISAS_TOO_MANY:
8436 gen_goto_tb(ctx, 0, ctx->base.pc_next);
8437 break;
8438 case DISAS_EXIT_UPDATE:
8439 gen_save_pc(ctx->base.pc_next);
8440 /* fall through */
8441 case DISAS_EXIT:
8442 tcg_gen_exit_tb(NULL, 0);
8443 break;
8444 case DISAS_JUMP:
8445 tcg_gen_lookup_and_goto_ptr();
8446 break;
8447 case DISAS_NORETURN:
8448 break;
8449 default:
8450 g_assert_not_reached();
8451 }
8452 }
8453
8454 static const TranslatorOps tricore_tr_ops = {
8455 .init_disas_context = tricore_tr_init_disas_context,
8456 .tb_start = tricore_tr_tb_start,
8457 .insn_start = tricore_tr_insn_start,
8458 .translate_insn = tricore_tr_translate_insn,
8459 .tb_stop = tricore_tr_tb_stop,
8460 };
8461
8462
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)8463 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
8464 vaddr pc, void *host_pc)
8465 {
8466 DisasContext ctx;
8467 translator_loop(cs, tb, max_insns, pc, host_pc,
8468 &tricore_tr_ops, &ctx.base);
8469 }
8470
8471 /*
8472 *
8473 * Initialization
8474 *
8475 */
8476
cpu_state_reset(CPUTriCoreState * env)8477 void cpu_state_reset(CPUTriCoreState *env)
8478 {
8479 /* Reset Regs to Default Value */
8480 env->PSW = 0xb80;
8481 fpu_set_state(env);
8482 }
8483
tricore_tcg_init_csfr(void)8484 static void tricore_tcg_init_csfr(void)
8485 {
8486 cpu_PCXI = tcg_global_mem_new(tcg_env,
8487 offsetof(CPUTriCoreState, PCXI), "PCXI");
8488 cpu_PSW = tcg_global_mem_new(tcg_env,
8489 offsetof(CPUTriCoreState, PSW), "PSW");
8490 cpu_PC = tcg_global_mem_new(tcg_env,
8491 offsetof(CPUTriCoreState, PC), "PC");
8492 cpu_ICR = tcg_global_mem_new(tcg_env,
8493 offsetof(CPUTriCoreState, ICR), "ICR");
8494 }
8495
tricore_tcg_init(void)8496 void tricore_tcg_init(void)
8497 {
8498 int i;
8499
8500 /* reg init */
8501 for (i = 0 ; i < 16 ; i++) {
8502 cpu_gpr_a[i] = tcg_global_mem_new(tcg_env,
8503 offsetof(CPUTriCoreState, gpr_a[i]),
8504 regnames_a[i]);
8505 }
8506 for (i = 0 ; i < 16 ; i++) {
8507 cpu_gpr_d[i] = tcg_global_mem_new(tcg_env,
8508 offsetof(CPUTriCoreState, gpr_d[i]),
8509 regnames_d[i]);
8510 }
8511 tricore_tcg_init_csfr();
8512 /* init PSW flag cache */
8513 cpu_PSW_C = tcg_global_mem_new(tcg_env,
8514 offsetof(CPUTriCoreState, PSW_USB_C),
8515 "PSW_C");
8516 cpu_PSW_V = tcg_global_mem_new(tcg_env,
8517 offsetof(CPUTriCoreState, PSW_USB_V),
8518 "PSW_V");
8519 cpu_PSW_SV = tcg_global_mem_new(tcg_env,
8520 offsetof(CPUTriCoreState, PSW_USB_SV),
8521 "PSW_SV");
8522 cpu_PSW_AV = tcg_global_mem_new(tcg_env,
8523 offsetof(CPUTriCoreState, PSW_USB_AV),
8524 "PSW_AV");
8525 cpu_PSW_SAV = tcg_global_mem_new(tcg_env,
8526 offsetof(CPUTriCoreState, PSW_USB_SAV),
8527 "PSW_SAV");
8528 }
8529