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