master
c 8,566 lines 289 KB
Raw
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 "tcg/tcg-op.h"
24 #include "accel/tcg/cpu-ldst.h"
25 #include "qemu/qemu-print.h"
26
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
29
30 #include "tricore-opcodes.h"
31 #include "exec/translator.h"
32 #include "exec/translation-block.h"
33 #include "exec/target_page.h"
34 #include "exec/log.h"
35
36 #define HELPER_H "helper.h"
37 #include "exec/helper-info.c.inc"
38 #undef HELPER_H
39
40 #define DISAS_EXIT DISAS_TARGET_0
41 #define DISAS_EXIT_UPDATE DISAS_TARGET_1
42 #define DISAS_JUMP DISAS_TARGET_2
43
44 /*
45 * TCG registers
46 */
47 static TCGv_i32 cpu_PC;
48 static TCGv_i32 cpu_PCXI;
49 static TCGv_i32 cpu_PSW;
50 static TCGv_i32 cpu_ICR;
51 /* GPR registers */
52 static TCGv_i32 cpu_gpr_a[16];
53 static TCGv_i32 cpu_gpr_d[16];
54 /* PSW Flag cache */
55 static TCGv_i32 cpu_PSW_C;
56 static TCGv_i32 cpu_PSW_V;
57 static TCGv_i32 cpu_PSW_SV;
58 static TCGv_i32 cpu_PSW_AV;
59 static TCGv_i32 cpu_PSW_SAV;
60
61 static const char *regnames_a[] = {
62 "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
63 "a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
64 "a12" , "a13" , "a14" , "a15",
65 };
66
67 static const char *regnames_d[] = {
68 "d0" , "d1" , "d2" , "d3" , "d4" , "d5" ,
69 "d6" , "d7" , "d8" , "d9" , "d10" , "d11" ,
70 "d12" , "d13" , "d14" , "d15",
71 };
72
73 typedef struct DisasContext {
74 DisasContextBase base;
75
76 vaddr pc_succ_insn;
77 uint32_t opcode;
78 /* Routine used to access memory */
79 int mem_idx;
80 int priv;
81 uint64_t features;
82 uint32_t icr_ie_mask, icr_ie_offset;
83 } DisasContext;
84
85 static int has_feature(DisasContext *ctx, int feature)
86 {
87 return (ctx->features & (1ULL << feature)) != 0;
88 }
89
90 enum {
91 MODE_LL = 0,
92 MODE_LU = 1,
93 MODE_UL = 2,
94 MODE_UU = 3,
95 };
96
97 void tricore_cpu_dump_state(CPUState *cs, FILE *f, int flags)
98 {
99 CPUTriCoreState *env = cpu_env(cs);
100 uint32_t psw;
101 int i;
102
103 psw = psw_read(env);
104
105 qemu_fprintf(f, "PC: " TARGET_FMT_lx, env->PC);
106 qemu_fprintf(f, " PSW: " TARGET_FMT_lx, psw);
107 qemu_fprintf(f, " ICR: " TARGET_FMT_lx, env->ICR);
108 qemu_fprintf(f, "\nPCXI: " TARGET_FMT_lx, env->PCXI);
109 qemu_fprintf(f, " FCX: " TARGET_FMT_lx, env->FCX);
110 qemu_fprintf(f, " LCX: " TARGET_FMT_lx, env->LCX);
111
112 for (i = 0; i < 16; ++i) {
113 if ((i & 3) == 0) {
114 qemu_fprintf(f, "\nGPR A%02d:", i);
115 }
116 qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_a[i]);
117 }
118 for (i = 0; i < 16; ++i) {
119 if ((i & 3) == 0) {
120 qemu_fprintf(f, "\nGPR D%02d:", i);
121 }
122 qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_d[i]);
123 }
124 qemu_fprintf(f, "\n");
125 }
126
127 /*
128 * Functions to generate micro-ops
129 */
130
131 /* Macros for generating helpers */
132
133 #define gen_helper_1arg(name, arg) do { \
134 TCGv_i32 helper_tmp = tcg_constant_i32(arg); \
135 gen_helper_##name(tcg_env, helper_tmp); \
136 } while (0)
137
138 #define GEN_HELPER_LL(name, ret, arg0, arg1, n) do { \
139 TCGv_i32 arg00 = tcg_temp_new_i32(); \
140 TCGv_i32 arg01 = tcg_temp_new_i32(); \
141 TCGv_i32 arg11 = tcg_temp_new_i32(); \
142 tcg_gen_sari_i32(arg00, arg0, 16); \
143 tcg_gen_ext16s_i32(arg01, arg0); \
144 tcg_gen_ext16s_i32(arg11, arg1); \
145 gen_helper_##name(ret, arg00, arg01, arg11, arg11, n); \
146 } while (0)
147
148 #define GEN_HELPER_LU(name, ret, arg0, arg1, n) do { \
149 TCGv_i32 arg00 = tcg_temp_new_i32(); \
150 TCGv_i32 arg01 = tcg_temp_new_i32(); \
151 TCGv_i32 arg10 = tcg_temp_new_i32(); \
152 TCGv_i32 arg11 = tcg_temp_new_i32(); \
153 tcg_gen_sari_i32(arg00, arg0, 16); \
154 tcg_gen_ext16s_i32(arg01, arg0); \
155 tcg_gen_sari_i32(arg11, arg1, 16); \
156 tcg_gen_ext16s_i32(arg10, arg1); \
157 gen_helper_##name(ret, arg00, arg01, arg10, arg11, n); \
158 } while (0)
159
160 #define GEN_HELPER_UL(name, ret, arg0, arg1, n) do { \
161 TCGv_i32 arg00 = tcg_temp_new_i32(); \
162 TCGv_i32 arg01 = tcg_temp_new_i32(); \
163 TCGv_i32 arg10 = tcg_temp_new_i32(); \
164 TCGv_i32 arg11 = tcg_temp_new_i32(); \
165 tcg_gen_sari_i32(arg00, arg0, 16); \
166 tcg_gen_ext16s_i32(arg01, arg0); \
167 tcg_gen_sari_i32(arg10, arg1, 16); \
168 tcg_gen_ext16s_i32(arg11, arg1); \
169 gen_helper_##name(ret, arg00, arg01, arg10, arg11, n); \
170 } while (0)
171
172 #define GEN_HELPER_UU(name, ret, arg0, arg1, n) do { \
173 TCGv_i32 arg00 = tcg_temp_new_i32(); \
174 TCGv_i32 arg01 = tcg_temp_new_i32(); \
175 TCGv_i32 arg11 = tcg_temp_new_i32(); \
176 tcg_gen_sari_i32(arg01, arg0, 16); \
177 tcg_gen_ext16s_i32(arg00, arg0); \
178 tcg_gen_sari_i32(arg11, arg1, 16); \
179 gen_helper_##name(ret, arg00, arg01, arg11, arg11, n); \
180 } while (0)
181
182 #define GEN_HELPER_RRR(name, rl, rh, al1, ah1, arg2) do { \
183 TCGv_i64 ret = tcg_temp_new_i64(); \
184 TCGv_i64 arg1 = tcg_temp_new_i64(); \
185 \
186 tcg_gen_concat_i32_i64(arg1, al1, ah1); \
187 gen_helper_##name(ret, arg1, arg2); \
188 tcg_gen_extr_i64_i32(rl, rh, ret); \
189 } while (0)
190
191 #define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do { \
192 TCGv_i64 ret = tcg_temp_new_i64(); \
193 \
194 gen_helper_##name(ret, tcg_env, arg1, arg2); \
195 tcg_gen_extr_i64_i32(rl, rh, ret); \
196 } while (0)
197
198 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
199 #define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
200 ((offset & 0x0fffff) << 1))
201
202 /* For two 32-bit registers used a 64-bit register, the first
203 registernumber needs to be even. Otherwise we trap. */
204 static void generate_trap(DisasContext *ctx, int class, int tin);
205 #define CHECK_REG_PAIR(reg) do { \
206 if (reg & 0x1) { \
207 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_OPD); \
208 } \
209 } while (0)
210
211 /* Functions for load/save to/from memory */
212
213 static void gen_offset_ld(DisasContext *ctx, TCGv_i32 r1, TCGv_i32 r2,
214 int16_t con, MemOp mop)
215 {
216 TCGv_i32 temp = tcg_temp_new_i32();
217 tcg_gen_addi_i32(temp, r2, con);
218 tcg_gen_qemu_ld_i32(r1, temp, ctx->mem_idx, mop);
219 }
220
221 static void gen_offset_st(DisasContext *ctx, TCGv_i32 r1, TCGv_i32 r2,
222 int16_t con, MemOp mop)
223 {
224 TCGv_i32 temp = tcg_temp_new_i32();
225 tcg_gen_addi_i32(temp, r2, con);
226 tcg_gen_qemu_st_i32(r1, temp, ctx->mem_idx, mop);
227 }
228
229 static void gen_st_2regs_64(DisasContext *ctx, TCGv_i32 rh, TCGv_i32 rl,
230 TCGv_i32 address)
231 {
232 TCGv_i64 temp = tcg_temp_new_i64();
233
234 tcg_gen_concat_i32_i64(temp, rl, rh);
235 tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEUQ);
236 }
237
238 static void gen_offset_st_2regs(DisasContext *ctx,
239 TCGv_i32 rh, TCGv_i32 rl,
240 TCGv_i32 base, int16_t con)
241 {
242 TCGv_i32 temp = tcg_temp_new_i32();
243 tcg_gen_addi_i32(temp, base, con);
244 gen_st_2regs_64(ctx, rh, rl, temp);
245 }
246
247 static void gen_ld_2regs_64(DisasContext *ctx, TCGv_i32 rh, TCGv_i32 rl,
248 TCGv_i32 address)
249 {
250 TCGv_i64 temp = tcg_temp_new_i64();
251
252 tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEUQ);
253 /* write back to two 32 bit regs */
254 tcg_gen_extr_i64_i32(rl, rh, temp);
255 }
256
257 static void gen_offset_ld_2regs(DisasContext *ctx,
258 TCGv_i32 rh, TCGv_i32 rl,
259 TCGv_i32 base, int16_t con)
260 {
261 TCGv_i32 temp = tcg_temp_new_i32();
262 tcg_gen_addi_i32(temp, base, con);
263 gen_ld_2regs_64(ctx, rh, rl, temp);
264 }
265
266 static void gen_st_preincr(DisasContext *ctx, TCGv_i32 r1, TCGv_i32 r2,
267 int16_t off, MemOp mop)
268 {
269 TCGv_i32 temp = tcg_temp_new_i32();
270 tcg_gen_addi_i32(temp, r2, off);
271 tcg_gen_qemu_st_i32(r1, temp, ctx->mem_idx, mop);
272 tcg_gen_mov_i32(r2, temp);
273 }
274
275 static void gen_ld_preincr(DisasContext *ctx, TCGv_i32 r1, TCGv_i32 r2,
276 int16_t off, MemOp mop)
277 {
278 TCGv_i32 temp = tcg_temp_new_i32();
279 tcg_gen_addi_i32(temp, r2, off);
280 tcg_gen_qemu_ld_i32(r1, temp, ctx->mem_idx, mop);
281 tcg_gen_mov_i32(r2, temp);
282 }
283
284 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
285 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv_i32 ea)
286 {
287 TCGv_i32 temp = tcg_temp_new_i32();
288 TCGv_i32 temp2 = tcg_temp_new_i32();
289
290 CHECK_REG_PAIR(ereg);
291 /* temp = (M(EA, word) */
292 tcg_gen_qemu_ld_i32(temp, ea, ctx->mem_idx, MO_LEUL);
293 /* temp = temp & ~E[a][63:32]) */
294 tcg_gen_andc_i32(temp, temp, cpu_gpr_d[ereg + 1]);
295 /* temp2 = (E[a][31:0] & E[a][63:32]); */
296 tcg_gen_and_i32(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg + 1]);
297 /* temp = temp | temp2; */
298 tcg_gen_or_i32(temp, temp, temp2);
299 /* M(EA, word) = temp; */
300 tcg_gen_qemu_st_i32(temp, ea, ctx->mem_idx, MO_LEUL);
301 }
302
303 /* tmp = M(EA, word);
304 M(EA, word) = D[a];
305 D[a] = tmp[31:0];*/
306 static void gen_swap(DisasContext *ctx, int reg, TCGv_i32 ea)
307 {
308 TCGv_i32 temp = tcg_temp_new_i32();
309
310 tcg_gen_qemu_ld_i32(temp, ea, ctx->mem_idx, MO_LEUL);
311 tcg_gen_qemu_st_i32(cpu_gpr_d[reg], ea, ctx->mem_idx, MO_LEUL);
312 tcg_gen_mov_i32(cpu_gpr_d[reg], temp);
313 }
314
315 static void gen_cmpswap(DisasContext *ctx, int reg, TCGv_i32 ea)
316 {
317 TCGv_i32 temp = tcg_temp_new_i32();
318 TCGv_i32 temp2 = tcg_temp_new_i32();
319 CHECK_REG_PAIR(reg);
320 tcg_gen_qemu_ld_i32(temp, ea, ctx->mem_idx, MO_LEUL);
321 tcg_gen_movcond_i32(TCG_COND_EQ, temp2, cpu_gpr_d[reg + 1], temp,
322 cpu_gpr_d[reg], temp);
323 tcg_gen_qemu_st_i32(temp2, ea, ctx->mem_idx, MO_LEUL);
324 tcg_gen_mov_i32(cpu_gpr_d[reg], temp);
325 }
326
327 static void gen_swapmsk(DisasContext *ctx, int reg, TCGv_i32 ea)
328 {
329 TCGv_i32 temp = tcg_temp_new_i32();
330 TCGv_i32 temp2 = tcg_temp_new_i32();
331 TCGv_i32 temp3 = tcg_temp_new_i32();
332 CHECK_REG_PAIR(reg);
333 tcg_gen_qemu_ld_i32(temp, ea, ctx->mem_idx, MO_LEUL);
334 tcg_gen_and_i32(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg + 1]);
335 tcg_gen_andc_i32(temp3, temp, cpu_gpr_d[reg + 1]);
336 tcg_gen_or_i32(temp2, temp2, temp3);
337 tcg_gen_qemu_st_i32(temp2, ea, ctx->mem_idx, MO_LEUL);
338 tcg_gen_mov_i32(cpu_gpr_d[reg], temp);
339 }
340
341 /* We generate loads and store to core special function register (csfr) through
342 the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
343 macros R, A and E, which allow read-only, all and endinit protected access.
344 These macros also specify in which ISA version the csfr was introduced. */
345 #define R(ADDRESS, REG, FEATURE) \
346 case ADDRESS: \
347 if (has_feature(ctx, FEATURE)) { \
348 tcg_gen_ld_i32(ret, tcg_env, offsetof(CPUTriCoreState, REG)); \
349 } \
350 break;
351 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
352 #define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
353 static void gen_mfcr(DisasContext *ctx, TCGv_i32 ret, int32_t offset)
354 {
355 /* since we're caching PSW make this a special case */
356 if (offset == 0xfe04) {
357 gen_helper_psw_read(ret, tcg_env);
358 } else {
359 switch (offset) {
360 #include "csfr.h.inc"
361 }
362 }
363 }
364 #undef R
365 #undef A
366 #undef E
367
368 #define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
369 since no exception occurs */
370 #define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
371 case ADDRESS: \
372 if (has_feature(ctx, FEATURE)) { \
373 tcg_gen_st_i32(r1, tcg_env, offsetof(CPUTriCoreState, REG)); \
374 } \
375 break;
376 /* Endinit protected registers
377 TODO: Since the endinit bit is in a register of a not yet implemented
378 watchdog device, we handle endinit protected registers like
379 all-access registers for now. */
380 #define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
381 static void gen_mtcr(DisasContext *ctx, TCGv_i32 r1, int32_t offset)
382 {
383 if (ctx->priv == TRICORE_PRIV_SM) {
384 /* since we're caching PSW make this a special case */
385 if (offset == 0xfe04) {
386 gen_helper_psw_write(tcg_env, r1);
387 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
388 } else {
389 switch (offset) {
390 #include "csfr.h.inc"
391 }
392 }
393 } else {
394 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
395 }
396 }
397
398 /* Functions for arithmetic instructions */
399
400 static void gen_add_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
401 {
402 TCGv_i32 t0 = tcg_temp_new_i32();
403 TCGv_i32 result = tcg_temp_new_i32();
404 /* Addition and set V/SV bits */
405 tcg_gen_add_i32(result, r1, r2);
406 /* calc V bit */
407 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
408 tcg_gen_xor_i32(t0, r1, r2);
409 tcg_gen_andc_i32(cpu_PSW_V, cpu_PSW_V, t0);
410 /* Calc SV bit */
411 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
412 /* Calc AV/SAV bits */
413 tcg_gen_add_i32(cpu_PSW_AV, result, result);
414 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
415 /* calc SAV */
416 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
417 /* write back result */
418 tcg_gen_mov_i32(ret, result);
419 }
420
421 static void gen_add64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
422 {
423 TCGv_i32 temp = tcg_temp_new_i32();
424 TCGv_i64 t0 = tcg_temp_new_i64();
425 TCGv_i64 t1 = tcg_temp_new_i64();
426 TCGv_i64 result = tcg_temp_new_i64();
427
428 tcg_gen_add_i64(result, r1, r2);
429 /* calc v bit */
430 tcg_gen_xor_i64(t1, result, r1);
431 tcg_gen_xor_i64(t0, r1, r2);
432 tcg_gen_andc_i64(t1, t1, t0);
433 tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
434 /* calc SV bit */
435 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
436 /* calc AV/SAV bits */
437 tcg_gen_extrh_i64_i32(temp, result);
438 tcg_gen_add_i32(cpu_PSW_AV, temp, temp);
439 tcg_gen_xor_i32(cpu_PSW_AV, temp, cpu_PSW_AV);
440 /* calc SAV */
441 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
442 /* write back result */
443 tcg_gen_mov_i64(ret, result);
444 }
445
446 static void gen_addsub64_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
447 TCGv_i32 r1_low, TCGv_i32 r1_high,
448 TCGv_i32 r2, TCGv_i32 r3,
449 void(*op1)(TCGv_i32, TCGv_i32, TCGv_i32),
450 void(*op2)(TCGv_i32, TCGv_i32, TCGv_i32))
451 {
452 TCGv_i32 temp = tcg_temp_new_i32();
453 TCGv_i32 temp2 = tcg_temp_new_i32();
454 TCGv_i32 temp3 = tcg_temp_new_i32();
455 TCGv_i32 temp4 = tcg_temp_new_i32();
456
457 (*op1)(temp, r1_low, r2);
458 /* calc V0 bit */
459 tcg_gen_xor_i32(temp2, temp, r1_low);
460 tcg_gen_xor_i32(temp3, r1_low, r2);
461 if (op1 == tcg_gen_add_tl) {
462 tcg_gen_andc_i32(temp2, temp2, temp3);
463 } else {
464 tcg_gen_and_i32(temp2, temp2, temp3);
465 }
466
467 (*op2)(temp3, r1_high, r3);
468 /* calc V1 bit */
469 tcg_gen_xor_i32(cpu_PSW_V, temp3, r1_high);
470 tcg_gen_xor_i32(temp4, r1_high, r3);
471 if (op2 == tcg_gen_add_tl) {
472 tcg_gen_andc_i32(cpu_PSW_V, cpu_PSW_V, temp4);
473 } else {
474 tcg_gen_and_i32(cpu_PSW_V, cpu_PSW_V, temp4);
475 }
476 /* combine V0/V1 bits */
477 tcg_gen_or_i32(cpu_PSW_V, cpu_PSW_V, temp2);
478 /* calc sv bit */
479 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
480 /* write result */
481 tcg_gen_mov_i32(ret_low, temp);
482 tcg_gen_mov_i32(ret_high, temp3);
483 /* calc AV bit */
484 tcg_gen_add_i32(temp, ret_low, ret_low);
485 tcg_gen_xor_i32(temp, temp, ret_low);
486 tcg_gen_add_i32(cpu_PSW_AV, ret_high, ret_high);
487 tcg_gen_xor_i32(cpu_PSW_AV, cpu_PSW_AV, ret_high);
488 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp);
489 /* calc SAV bit */
490 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
491 }
492
493 /* ret = r2 + (r1 * r3); */
494 static void gen_madd32_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3)
495 {
496 TCGv_i64 t1 = tcg_temp_new_i64();
497 TCGv_i64 t2 = tcg_temp_new_i64();
498 TCGv_i64 t3 = tcg_temp_new_i64();
499
500 tcg_gen_ext_i32_i64(t1, r1);
501 tcg_gen_ext_i32_i64(t2, r2);
502 tcg_gen_ext_i32_i64(t3, r3);
503
504 tcg_gen_mul_i64(t1, t1, t3);
505 tcg_gen_add_i64(t1, t2, t1);
506
507 tcg_gen_extrl_i64_i32(ret, t1);
508 /* calc V
509 t1 > 0x7fffffff */
510 tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
511 /* t1 < -0x80000000 */
512 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
513 tcg_gen_or_i64(t2, t2, t3);
514 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
515 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
516 /* Calc SV bit */
517 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
518 /* Calc AV/SAV bits */
519 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
520 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
521 /* calc SAV */
522 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
523 }
524
525 static void gen_maddi32_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
526 {
527 TCGv_i32 temp = tcg_constant_i32(con);
528 gen_madd32_d(ret, r1, r2, temp);
529 }
530
531 static void gen_madd64_d(TCGv_i32 ret_low, TCGv_i32 ret_high, TCGv_i32 r1,
532 TCGv_i32 r2_low, TCGv_i32 r2_high, TCGv_i32 r3)
533 {
534 TCGv_i32 t1 = tcg_temp_new_i32();
535 TCGv_i32 t2 = tcg_temp_new_i32();
536 TCGv_i32 t3 = tcg_temp_new_i32();
537 TCGv_i32 t4 = tcg_temp_new_i32();
538
539 tcg_gen_muls2_i32(t1, t2, r1, r3);
540 /* only the add can overflow */
541 tcg_gen_add2_i32(t3, t4, r2_low, r2_high, t1, t2);
542 /* calc V bit */
543 tcg_gen_xor_i32(cpu_PSW_V, t4, r2_high);
544 tcg_gen_xor_i32(t1, r2_high, t2);
545 tcg_gen_andc_i32(cpu_PSW_V, cpu_PSW_V, t1);
546 /* Calc SV bit */
547 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
548 /* Calc AV/SAV bits */
549 tcg_gen_add_i32(cpu_PSW_AV, t4, t4);
550 tcg_gen_xor_i32(cpu_PSW_AV, t4, cpu_PSW_AV);
551 /* calc SAV */
552 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
553 /* write back the result */
554 tcg_gen_mov_i32(ret_low, t3);
555 tcg_gen_mov_i32(ret_high, t4);
556 }
557
558 static void gen_maddu64_d(TCGv_i32 ret_low, TCGv_i32 ret_high, TCGv_i32 r1,
559 TCGv_i32 r2_low, TCGv_i32 r2_high, TCGv_i32 r3)
560 {
561 TCGv_i64 t1 = tcg_temp_new_i64();
562 TCGv_i64 t2 = tcg_temp_new_i64();
563 TCGv_i64 t3 = tcg_temp_new_i64();
564
565 tcg_gen_extu_i32_i64(t1, r1);
566 tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
567 tcg_gen_extu_i32_i64(t3, r3);
568
569 tcg_gen_mul_i64(t1, t1, t3);
570 tcg_gen_add_i64(t2, t2, t1);
571 /* write back result */
572 tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
573 /* only the add overflows, if t2 < t1
574 calc V bit */
575 tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
576 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
577 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
578 /* Calc SV bit */
579 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
580 /* Calc AV/SAV bits */
581 tcg_gen_add_i32(cpu_PSW_AV, ret_high, ret_high);
582 tcg_gen_xor_i32(cpu_PSW_AV, ret_high, cpu_PSW_AV);
583 /* calc SAV */
584 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
585 }
586
587 static void gen_maddi64_d(TCGv_i32 ret_low, TCGv_i32 ret_high, TCGv_i32 r1,
588 TCGv_i32 r2_low, TCGv_i32 r2_high, int32_t con)
589 {
590 TCGv_i32 temp = tcg_constant_i32(con);
591 gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
592 }
593
594 static void gen_maddui64_d(TCGv_i32 ret_low, TCGv_i32 ret_high, TCGv_i32 r1,
595 TCGv_i32 r2_low, TCGv_i32 r2_high, int32_t con)
596 {
597 TCGv_i32 temp = tcg_constant_i32(con);
598 gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
599 }
600
601 static void gen_madd_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
602 TCGv_i32 r1_low, TCGv_i32 r1_high,
603 TCGv_i32 r2, TCGv_i32 r3,
604 uint32_t n, uint32_t mode)
605 {
606 TCGv_i32 t_n = tcg_constant_i32(n);
607 TCGv_i32 temp = tcg_temp_new_i32();
608 TCGv_i32 temp2 = tcg_temp_new_i32();
609 TCGv_i64 temp64 = tcg_temp_new_i64();
610 switch (mode) {
611 case MODE_LL:
612 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
613 break;
614 case MODE_LU:
615 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
616 break;
617 case MODE_UL:
618 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
619 break;
620 case MODE_UU:
621 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
622 break;
623 }
624 tcg_gen_extr_i64_i32(temp, temp2, temp64);
625 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
626 tcg_gen_add_tl, tcg_gen_add_tl);
627 }
628
629 static void gen_maddsu_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
630 TCGv_i32 r1_low, TCGv_i32 r1_high,
631 TCGv_i32 r2, TCGv_i32 r3,
632 uint32_t n, uint32_t mode)
633 {
634 TCGv_i32 t_n = tcg_constant_i32(n);
635 TCGv_i32 temp = tcg_temp_new_i32();
636 TCGv_i32 temp2 = tcg_temp_new_i32();
637 TCGv_i64 temp64 = tcg_temp_new_i64();
638 switch (mode) {
639 case MODE_LL:
640 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
641 break;
642 case MODE_LU:
643 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
644 break;
645 case MODE_UL:
646 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
647 break;
648 case MODE_UU:
649 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
650 break;
651 }
652 tcg_gen_extr_i64_i32(temp, temp2, temp64);
653 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
654 tcg_gen_sub_tl, tcg_gen_add_tl);
655 }
656
657 static void gen_maddsum_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
658 TCGv_i32 r1_low, TCGv_i32 r1_high,
659 TCGv_i32 r2, TCGv_i32 r3,
660 uint32_t n, uint32_t mode)
661 {
662 TCGv_i32 t_n = tcg_constant_i32(n);
663 TCGv_i64 temp64 = tcg_temp_new_i64();
664 TCGv_i64 temp64_2 = tcg_temp_new_i64();
665 TCGv_i64 temp64_3 = tcg_temp_new_i64();
666 switch (mode) {
667 case MODE_LL:
668 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
669 break;
670 case MODE_LU:
671 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
672 break;
673 case MODE_UL:
674 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
675 break;
676 case MODE_UU:
677 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
678 break;
679 }
680 tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
681 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
682 tcg_gen_ext32s_i64(temp64, temp64); /* low */
683 tcg_gen_sub_i64(temp64, temp64_2, temp64);
684 tcg_gen_shli_i64(temp64, temp64, 16);
685
686 gen_add64_d(temp64_2, temp64_3, temp64);
687 /* write back result */
688 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
689 }
690
691 static void gen_adds(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2);
692
693 static void gen_madds_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
694 TCGv_i32 r1_low, TCGv_i32 r1_high,
695 TCGv_i32 r2, TCGv_i32 r3,
696 uint32_t n, uint32_t mode)
697 {
698 TCGv_i32 t_n = tcg_constant_i32(n);
699 TCGv_i32 temp = tcg_temp_new_i32();
700 TCGv_i32 temp2 = tcg_temp_new_i32();
701 TCGv_i32 temp3 = tcg_temp_new_i32();
702 TCGv_i64 temp64 = tcg_temp_new_i64();
703
704 switch (mode) {
705 case MODE_LL:
706 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
707 break;
708 case MODE_LU:
709 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
710 break;
711 case MODE_UL:
712 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
713 break;
714 case MODE_UU:
715 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
716 break;
717 }
718 tcg_gen_extr_i64_i32(temp, temp2, temp64);
719 gen_adds(ret_low, r1_low, temp);
720 tcg_gen_mov_i32(temp, cpu_PSW_V);
721 tcg_gen_mov_i32(temp3, cpu_PSW_AV);
722 gen_adds(ret_high, r1_high, temp2);
723 /* combine v bits */
724 tcg_gen_or_i32(cpu_PSW_V, cpu_PSW_V, temp);
725 /* combine av bits */
726 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp3);
727 }
728
729 static void gen_subs(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2);
730
731 static void gen_maddsus_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
732 TCGv_i32 r1_low, TCGv_i32 r1_high,
733 TCGv_i32 r2, TCGv_i32 r3,
734 uint32_t n, uint32_t mode)
735 {
736 TCGv_i32 t_n = tcg_constant_i32(n);
737 TCGv_i32 temp = tcg_temp_new_i32();
738 TCGv_i32 temp2 = tcg_temp_new_i32();
739 TCGv_i32 temp3 = tcg_temp_new_i32();
740 TCGv_i64 temp64 = tcg_temp_new_i64();
741
742 switch (mode) {
743 case MODE_LL:
744 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
745 break;
746 case MODE_LU:
747 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
748 break;
749 case MODE_UL:
750 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
751 break;
752 case MODE_UU:
753 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
754 break;
755 }
756 tcg_gen_extr_i64_i32(temp, temp2, temp64);
757 gen_subs(ret_low, r1_low, temp);
758 tcg_gen_mov_i32(temp, cpu_PSW_V);
759 tcg_gen_mov_i32(temp3, cpu_PSW_AV);
760 gen_adds(ret_high, r1_high, temp2);
761 /* combine v bits */
762 tcg_gen_or_i32(cpu_PSW_V, cpu_PSW_V, temp);
763 /* combine av bits */
764 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp3);
765 }
766
767 static void gen_maddsums_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
768 TCGv_i32 r1_low, TCGv_i32 r1_high,
769 TCGv_i32 r2, TCGv_i32 r3,
770 uint32_t n, uint32_t mode)
771 {
772 TCGv_i32 t_n = tcg_constant_i32(n);
773 TCGv_i64 temp64 = tcg_temp_new_i64();
774 TCGv_i64 temp64_2 = tcg_temp_new_i64();
775
776 switch (mode) {
777 case MODE_LL:
778 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
779 break;
780 case MODE_LU:
781 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
782 break;
783 case MODE_UL:
784 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
785 break;
786 case MODE_UU:
787 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
788 break;
789 }
790 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
791 tcg_gen_ext32s_i64(temp64, temp64); /* low */
792 tcg_gen_sub_i64(temp64, temp64_2, temp64);
793 tcg_gen_shli_i64(temp64, temp64, 16);
794 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
795
796 gen_helper_add64_ssov(temp64, tcg_env, temp64_2, temp64);
797 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
798 }
799
800
801 static void gen_maddm_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
802 TCGv_i32 r1_low, TCGv_i32 r1_high,
803 TCGv_i32 r2, TCGv_i32 r3,
804 uint32_t n, uint32_t mode)
805 {
806 TCGv_i32 t_n = tcg_constant_i32(n);
807 TCGv_i64 temp64 = tcg_temp_new_i64();
808 TCGv_i64 temp64_2 = tcg_temp_new_i64();
809 TCGv_i64 temp64_3 = tcg_temp_new_i64();
810 switch (mode) {
811 case MODE_LL:
812 GEN_HELPER_LL(mulm_h, temp64, r2, r3, t_n);
813 break;
814 case MODE_LU:
815 GEN_HELPER_LU(mulm_h, temp64, r2, r3, t_n);
816 break;
817 case MODE_UL:
818 GEN_HELPER_UL(mulm_h, temp64, r2, r3, t_n);
819 break;
820 case MODE_UU:
821 GEN_HELPER_UU(mulm_h, temp64, r2, r3, t_n);
822 break;
823 }
824 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
825 gen_add64_d(temp64_3, temp64_2, temp64);
826 /* write back result */
827 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
828 }
829
830 static void gen_maddms_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
831 TCGv_i32 r1_low, TCGv_i32 r1_high,
832 TCGv_i32 r2, TCGv_i32 r3,
833 uint32_t n, uint32_t mode)
834 {
835 TCGv_i32 t_n = tcg_constant_i32(n);
836 TCGv_i64 temp64 = tcg_temp_new_i64();
837 TCGv_i64 temp64_2 = tcg_temp_new_i64();
838 switch (mode) {
839 case MODE_LL:
840 GEN_HELPER_LL(mulm_h, temp64, r2, r3, t_n);
841 break;
842 case MODE_LU:
843 GEN_HELPER_LU(mulm_h, temp64, r2, r3, t_n);
844 break;
845 case MODE_UL:
846 GEN_HELPER_UL(mulm_h, temp64, r2, r3, t_n);
847 break;
848 case MODE_UU:
849 GEN_HELPER_UU(mulm_h, temp64, r2, r3, t_n);
850 break;
851 }
852 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
853 gen_helper_add64_ssov(temp64, tcg_env, temp64_2, temp64);
854 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
855 }
856
857 static void gen_maddr64_h(TCGv_i32 ret, TCGv_i32 r1_low, TCGv_i32 r1_high,
858 TCGv_i32 r2, TCGv_i32 r3,
859 uint32_t n, uint32_t mode)
860 {
861 TCGv_i32 t_n = tcg_constant_i32(n);
862 TCGv_i64 temp64 = tcg_temp_new_i64();
863 switch (mode) {
864 case MODE_LL:
865 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
866 break;
867 case MODE_LU:
868 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
869 break;
870 case MODE_UL:
871 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
872 break;
873 case MODE_UU:
874 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
875 break;
876 }
877 gen_helper_addr_h(ret, tcg_env, temp64, r1_low, r1_high);
878 }
879
880 static void gen_maddr32_h(TCGv_i32 ret,
881 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
882 uint32_t n, uint32_t mode)
883 {
884 TCGv_i32 temp = tcg_temp_new_i32();
885 TCGv_i32 temp2 = tcg_temp_new_i32();
886
887 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
888 tcg_gen_shli_i32(temp, r1, 16);
889 gen_maddr64_h(ret, temp, temp2, r2, r3, n, mode);
890 }
891
892 static void gen_maddsur32_h(TCGv_i32 ret,
893 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
894 uint32_t n, uint32_t mode)
895 {
896 TCGv_i32 t_n = tcg_constant_i32(n);
897 TCGv_i32 temp = tcg_temp_new_i32();
898 TCGv_i32 temp2 = tcg_temp_new_i32();
899 TCGv_i64 temp64 = tcg_temp_new_i64();
900 switch (mode) {
901 case MODE_LL:
902 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
903 break;
904 case MODE_LU:
905 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
906 break;
907 case MODE_UL:
908 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
909 break;
910 case MODE_UU:
911 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
912 break;
913 }
914 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
915 tcg_gen_shli_i32(temp, r1, 16);
916 gen_helper_addsur_h(ret, tcg_env, temp64, temp, temp2);
917 }
918
919
920 static void gen_maddr64s_h(TCGv_i32 ret, TCGv_i32 r1_low, TCGv_i32 r1_high,
921 TCGv_i32 r2, TCGv_i32 r3,
922 uint32_t n, uint32_t mode)
923 {
924 TCGv_i32 t_n = tcg_constant_i32(n);
925 TCGv_i64 temp64 = tcg_temp_new_i64();
926 switch (mode) {
927 case MODE_LL:
928 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
929 break;
930 case MODE_LU:
931 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
932 break;
933 case MODE_UL:
934 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
935 break;
936 case MODE_UU:
937 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
938 break;
939 }
940 gen_helper_addr_h_ssov(ret, tcg_env, temp64, r1_low, r1_high);
941 }
942
943 static void gen_maddr32s_h(TCGv_i32 ret,
944 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
945 uint32_t n, uint32_t mode)
946 {
947 TCGv_i32 temp = tcg_temp_new_i32();
948 TCGv_i32 temp2 = tcg_temp_new_i32();
949
950 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
951 tcg_gen_shli_i32(temp, r1, 16);
952 gen_maddr64s_h(ret, temp, temp2, r2, r3, n, mode);
953 }
954
955 static void gen_maddsur32s_h(TCGv_i32 ret,
956 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
957 uint32_t n, uint32_t mode)
958 {
959 TCGv_i32 t_n = tcg_constant_i32(n);
960 TCGv_i32 temp = tcg_temp_new_i32();
961 TCGv_i32 temp2 = tcg_temp_new_i32();
962 TCGv_i64 temp64 = tcg_temp_new_i64();
963 switch (mode) {
964 case MODE_LL:
965 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
966 break;
967 case MODE_LU:
968 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
969 break;
970 case MODE_UL:
971 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
972 break;
973 case MODE_UU:
974 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
975 break;
976 }
977 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
978 tcg_gen_shli_i32(temp, r1, 16);
979 gen_helper_addsur_h_ssov(ret, tcg_env, temp64, temp, temp2);
980 }
981
982 static void gen_maddr_q(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
983 uint32_t n)
984 {
985 TCGv_i32 t_n = tcg_constant_i32(n);
986 gen_helper_maddr_q(ret, tcg_env, r1, r2, r3, t_n);
987 }
988
989 static void gen_maddrs_q(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
990 uint32_t n)
991 {
992 TCGv_i32 t_n = tcg_constant_i32(n);
993 gen_helper_maddr_q_ssov(ret, tcg_env, r1, r2, r3, t_n);
994 }
995
996 static void gen_madd32_q(TCGv_i32 ret,
997 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
998 uint32_t n, uint32_t up_shift)
999 {
1000 TCGv_i32 temp = tcg_temp_new_i32();
1001 TCGv_i32 temp2 = tcg_temp_new_i32();
1002 TCGv_i32 temp3 = tcg_temp_new_i32();
1003 TCGv_i64 t1 = tcg_temp_new_i64();
1004 TCGv_i64 t2 = tcg_temp_new_i64();
1005 TCGv_i64 t3 = tcg_temp_new_i64();
1006
1007 tcg_gen_ext_i32_i64(t2, arg2);
1008 tcg_gen_ext_i32_i64(t3, arg3);
1009
1010 tcg_gen_mul_i64(t2, t2, t3);
1011 tcg_gen_shli_i64(t2, t2, n);
1012
1013 tcg_gen_ext_i32_i64(t1, arg1);
1014 tcg_gen_sari_i64(t2, t2, up_shift);
1015
1016 tcg_gen_add_i64(t3, t1, t2);
1017 tcg_gen_extrl_i64_i32(temp3, t3);
1018 /* calc v bit */
1019 tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1020 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1021 tcg_gen_or_i64(t1, t1, t2);
1022 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1023 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
1024 /* We produce an overflow on the host if the mul before was
1025 (0x80000000 * 0x80000000) << 1). If this is the
1026 case, we negate the ovf. */
1027 if (n == 1) {
1028 tcg_gen_setcondi_i32(TCG_COND_EQ, temp, arg2, 0x80000000);
1029 tcg_gen_setcond_i32(TCG_COND_EQ, temp2, arg2, arg3);
1030 tcg_gen_and_i32(temp, temp, temp2);
1031 tcg_gen_shli_i32(temp, temp, 31);
1032 /* negate v bit, if special condition */
1033 tcg_gen_xor_i32(cpu_PSW_V, cpu_PSW_V, temp);
1034 }
1035 /* Calc SV bit */
1036 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1037 /* Calc AV/SAV bits */
1038 tcg_gen_add_i32(cpu_PSW_AV, temp3, temp3);
1039 tcg_gen_xor_i32(cpu_PSW_AV, temp3, cpu_PSW_AV);
1040 /* calc SAV */
1041 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1042 /* write back result */
1043 tcg_gen_mov_i32(ret, temp3);
1044 }
1045
1046 static void gen_m16add32_q(TCGv_i32 ret,
1047 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1048 uint32_t n)
1049 {
1050 TCGv_i32 temp = tcg_temp_new_i32();
1051 TCGv_i32 temp2 = tcg_temp_new_i32();
1052 if (n == 0) {
1053 tcg_gen_mul_i32(temp, arg2, arg3);
1054 } else { /* n is expected to be 1 */
1055 tcg_gen_mul_i32(temp, arg2, arg3);
1056 tcg_gen_shli_i32(temp, temp, 1);
1057 /* catch special case r1 = r2 = 0x8000 */
1058 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1059 tcg_gen_sub_i32(temp, temp, temp2);
1060 }
1061 gen_add_d(ret, arg1, temp);
1062 }
1063
1064 static void gen_m16adds32_q(TCGv_i32 ret,
1065 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1066 uint32_t n)
1067 {
1068 TCGv_i32 temp = tcg_temp_new_i32();
1069 TCGv_i32 temp2 = tcg_temp_new_i32();
1070 if (n == 0) {
1071 tcg_gen_mul_i32(temp, arg2, arg3);
1072 } else { /* n is expected to be 1 */
1073 tcg_gen_mul_i32(temp, arg2, arg3);
1074 tcg_gen_shli_i32(temp, temp, 1);
1075 /* catch special case r1 = r2 = 0x8000 */
1076 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1077 tcg_gen_sub_i32(temp, temp, temp2);
1078 }
1079 gen_adds(ret, arg1, temp);
1080 }
1081
1082 static void gen_m16add64_q(TCGv_i32 rl, TCGv_i32 rh,
1083 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1084 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1085 {
1086 TCGv_i32 temp = tcg_temp_new_i32();
1087 TCGv_i32 temp2 = tcg_temp_new_i32();
1088 TCGv_i64 t1 = tcg_temp_new_i64();
1089 TCGv_i64 t2 = tcg_temp_new_i64();
1090 TCGv_i64 t3 = tcg_temp_new_i64();
1091
1092 if (n == 0) {
1093 tcg_gen_mul_i32(temp, arg2, arg3);
1094 } else { /* n is expected to be 1 */
1095 tcg_gen_mul_i32(temp, arg2, arg3);
1096 tcg_gen_shli_i32(temp, temp, 1);
1097 /* catch special case r1 = r2 = 0x8000 */
1098 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1099 tcg_gen_sub_i32(temp, temp, temp2);
1100 }
1101 tcg_gen_ext_i32_i64(t2, temp);
1102 tcg_gen_shli_i64(t2, t2, 16);
1103 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1104 gen_add64_d(t3, t1, t2);
1105 /* write back result */
1106 tcg_gen_extr_i64_i32(rl, rh, t3);
1107 }
1108
1109 static void gen_m16adds64_q(TCGv_i32 rl, TCGv_i32 rh,
1110 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1111 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1112 {
1113 TCGv_i32 temp = tcg_temp_new_i32();
1114 TCGv_i32 temp2 = tcg_temp_new_i32();
1115 TCGv_i64 t1 = tcg_temp_new_i64();
1116 TCGv_i64 t2 = tcg_temp_new_i64();
1117
1118 if (n == 0) {
1119 tcg_gen_mul_i32(temp, arg2, arg3);
1120 } else { /* n is expected to be 1 */
1121 tcg_gen_mul_i32(temp, arg2, arg3);
1122 tcg_gen_shli_i32(temp, temp, 1);
1123 /* catch special case r1 = r2 = 0x8000 */
1124 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1125 tcg_gen_sub_i32(temp, temp, temp2);
1126 }
1127 tcg_gen_ext_i32_i64(t2, temp);
1128 tcg_gen_shli_i64(t2, t2, 16);
1129 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1130
1131 gen_helper_add64_ssov(t1, tcg_env, t1, t2);
1132 tcg_gen_extr_i64_i32(rl, rh, t1);
1133 }
1134
1135 static void gen_madd64_q(TCGv_i32 rl, TCGv_i32 rh,
1136 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1137 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1138 {
1139 TCGv_i64 t1 = tcg_temp_new_i64();
1140 TCGv_i64 t2 = tcg_temp_new_i64();
1141 TCGv_i64 t3 = tcg_temp_new_i64();
1142 TCGv_i64 t4 = tcg_temp_new_i64();
1143 TCGv_i32 temp, temp2;
1144
1145 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1146 tcg_gen_ext_i32_i64(t2, arg2);
1147 tcg_gen_ext_i32_i64(t3, arg3);
1148
1149 tcg_gen_mul_i64(t2, t2, t3);
1150 if (n != 0) {
1151 tcg_gen_shli_i64(t2, t2, 1);
1152 }
1153 tcg_gen_add_i64(t4, t1, t2);
1154 /* calc v bit */
1155 tcg_gen_xor_i64(t3, t4, t1);
1156 tcg_gen_xor_i64(t2, t1, t2);
1157 tcg_gen_andc_i64(t3, t3, t2);
1158 tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
1159 /* We produce an overflow on the host if the mul before was
1160 (0x80000000 * 0x80000000) << 1). If this is the
1161 case, we negate the ovf. */
1162 if (n == 1) {
1163 temp = tcg_temp_new_i32();
1164 temp2 = tcg_temp_new_i32();
1165 tcg_gen_setcondi_i32(TCG_COND_EQ, temp, arg2, 0x80000000);
1166 tcg_gen_setcond_i32(TCG_COND_EQ, temp2, arg2, arg3);
1167 tcg_gen_and_i32(temp, temp, temp2);
1168 tcg_gen_shli_i32(temp, temp, 31);
1169 /* negate v bit, if special condition */
1170 tcg_gen_xor_i32(cpu_PSW_V, cpu_PSW_V, temp);
1171 }
1172 /* write back result */
1173 tcg_gen_extr_i64_i32(rl, rh, t4);
1174 /* Calc SV bit */
1175 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1176 /* Calc AV/SAV bits */
1177 tcg_gen_add_i32(cpu_PSW_AV, rh, rh);
1178 tcg_gen_xor_i32(cpu_PSW_AV, rh, cpu_PSW_AV);
1179 /* calc SAV */
1180 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1181 }
1182
1183 static void gen_madds32_q(TCGv_i32 ret,
1184 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1185 uint32_t n, uint32_t up_shift)
1186 {
1187 TCGv_i64 t1 = tcg_temp_new_i64();
1188 TCGv_i64 t2 = tcg_temp_new_i64();
1189 TCGv_i64 t3 = tcg_temp_new_i64();
1190
1191 tcg_gen_ext_i32_i64(t1, arg1);
1192 tcg_gen_ext_i32_i64(t2, arg2);
1193 tcg_gen_ext_i32_i64(t3, arg3);
1194
1195 tcg_gen_mul_i64(t2, t2, t3);
1196 tcg_gen_sari_i64(t2, t2, up_shift - n);
1197
1198 gen_helper_madd32_q_add_ssov(ret, tcg_env, t1, t2);
1199 }
1200
1201 static void gen_madds64_q(TCGv_i32 rl, TCGv_i32 rh,
1202 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1203 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1204 {
1205 TCGv_i64 r1 = tcg_temp_new_i64();
1206 TCGv_i32 t_n = tcg_constant_i32(n);
1207
1208 tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
1209 gen_helper_madd64_q_ssov(r1, tcg_env, r1, arg2, arg3, t_n);
1210 tcg_gen_extr_i64_i32(rl, rh, r1);
1211 }
1212
1213 /* ret = r2 - (r1 * r3); */
1214 static void gen_msub32_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3)
1215 {
1216 TCGv_i64 t1 = tcg_temp_new_i64();
1217 TCGv_i64 t2 = tcg_temp_new_i64();
1218 TCGv_i64 t3 = tcg_temp_new_i64();
1219
1220 tcg_gen_ext_i32_i64(t1, r1);
1221 tcg_gen_ext_i32_i64(t2, r2);
1222 tcg_gen_ext_i32_i64(t3, r3);
1223
1224 tcg_gen_mul_i64(t1, t1, t3);
1225 tcg_gen_sub_i64(t1, t2, t1);
1226
1227 tcg_gen_extrl_i64_i32(ret, t1);
1228 /* calc V
1229 t2 > 0x7fffffff */
1230 tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
1231 /* result < -0x80000000 */
1232 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
1233 tcg_gen_or_i64(t2, t2, t3);
1234 tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
1235 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
1236
1237 /* Calc SV bit */
1238 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1239 /* Calc AV/SAV bits */
1240 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
1241 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
1242 /* calc SAV */
1243 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1244 }
1245
1246 static void gen_msubi32_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
1247 {
1248 TCGv_i32 temp = tcg_constant_i32(con);
1249 gen_msub32_d(ret, r1, r2, temp);
1250 }
1251
1252 static void gen_msub64_d(TCGv_i32 ret_low, TCGv_i32 ret_high,
1253 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
1254 TCGv_i32 r3)
1255 {
1256 TCGv_i32 t1 = tcg_temp_new_i32();
1257 TCGv_i32 t2 = tcg_temp_new_i32();
1258 TCGv_i32 t3 = tcg_temp_new_i32();
1259 TCGv_i32 t4 = tcg_temp_new_i32();
1260
1261 tcg_gen_muls2_i32(t1, t2, r1, r3);
1262 /* only the sub can overflow */
1263 tcg_gen_sub2_i32(t3, t4, r2_low, r2_high, t1, t2);
1264 /* calc V bit */
1265 tcg_gen_xor_i32(cpu_PSW_V, t4, r2_high);
1266 tcg_gen_xor_i32(t1, r2_high, t2);
1267 tcg_gen_and_i32(cpu_PSW_V, cpu_PSW_V, t1);
1268 /* Calc SV bit */
1269 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1270 /* Calc AV/SAV bits */
1271 tcg_gen_add_i32(cpu_PSW_AV, t4, t4);
1272 tcg_gen_xor_i32(cpu_PSW_AV, t4, cpu_PSW_AV);
1273 /* calc SAV */
1274 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1275 /* write back the result */
1276 tcg_gen_mov_i32(ret_low, t3);
1277 tcg_gen_mov_i32(ret_high, t4);
1278 }
1279
1280 static void gen_msubi64_d(TCGv_i32 ret_low, TCGv_i32 ret_high,
1281 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
1282 int32_t con)
1283 {
1284 TCGv_i32 temp = tcg_constant_i32(con);
1285 gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1286 }
1287
1288 static void gen_msubu64_d(TCGv_i32 ret_low, TCGv_i32 ret_high, TCGv_i32 r1,
1289 TCGv_i32 r2_low, TCGv_i32 r2_high, TCGv_i32 r3)
1290 {
1291 TCGv_i64 t1 = tcg_temp_new_i64();
1292 TCGv_i64 t2 = tcg_temp_new_i64();
1293 TCGv_i64 t3 = tcg_temp_new_i64();
1294
1295 tcg_gen_extu_i32_i64(t1, r1);
1296 tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
1297 tcg_gen_extu_i32_i64(t3, r3);
1298
1299 tcg_gen_mul_i64(t1, t1, t3);
1300 tcg_gen_sub_i64(t3, t2, t1);
1301 tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
1302 /* calc V bit, only the sub can overflow, if t1 > t2 */
1303 tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
1304 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1305 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
1306 /* Calc SV bit */
1307 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1308 /* Calc AV/SAV bits */
1309 tcg_gen_add_i32(cpu_PSW_AV, ret_high, ret_high);
1310 tcg_gen_xor_i32(cpu_PSW_AV, ret_high, cpu_PSW_AV);
1311 /* calc SAV */
1312 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1313 }
1314
1315 static void gen_msubui64_d(TCGv_i32 ret_low, TCGv_i32 ret_high,
1316 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
1317 int32_t con)
1318 {
1319 TCGv_i32 temp = tcg_constant_i32(con);
1320 gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1321 }
1322
1323 static void gen_addi_d(TCGv_i32 ret, TCGv_i32 r1, int32_t r2)
1324 {
1325 TCGv_i32 temp = tcg_constant_i32(r2);
1326 gen_add_d(ret, r1, temp);
1327 }
1328
1329 /* calculate the carry bit too */
1330 static void gen_add_CC(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
1331 {
1332 TCGv_i32 t0 = tcg_temp_new_i32();
1333 TCGv_i32 result = tcg_temp_new_i32();
1334
1335 tcg_gen_movi_i32(t0, 0);
1336 /* Addition and set C/V/SV bits */
1337 tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, r2, t0);
1338 /* calc V bit */
1339 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
1340 tcg_gen_xor_i32(t0, r1, r2);
1341 tcg_gen_andc_i32(cpu_PSW_V, cpu_PSW_V, t0);
1342 /* Calc SV bit */
1343 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1344 /* Calc AV/SAV bits */
1345 tcg_gen_add_i32(cpu_PSW_AV, result, result);
1346 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
1347 /* calc SAV */
1348 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1349 /* write back result */
1350 tcg_gen_mov_i32(ret, result);
1351 }
1352
1353 static void gen_addi_CC(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
1354 {
1355 TCGv_i32 temp = tcg_constant_i32(con);
1356 gen_add_CC(ret, r1, temp);
1357 }
1358
1359 static void gen_addc_CC(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
1360 {
1361 TCGv_i32 t0 = tcg_temp_new_i32();
1362 TCGv_i32 result = tcg_temp_new_i32();
1363
1364 /* Addition, carry and set C/V/SV bits */
1365 tcg_gen_addcio_i32(result, cpu_PSW_C, r1, r2, cpu_PSW_C);
1366 /* calc V bit */
1367 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
1368 tcg_gen_xor_i32(t0, r1, r2);
1369 tcg_gen_andc_i32(cpu_PSW_V, cpu_PSW_V, t0);
1370 /* Calc SV bit */
1371 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1372 /* Calc AV/SAV bits */
1373 tcg_gen_add_i32(cpu_PSW_AV, result, result);
1374 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
1375 /* calc SAV */
1376 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1377 /* write back result */
1378 tcg_gen_mov_i32(ret, result);
1379 }
1380
1381 static void gen_addci_CC(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
1382 {
1383 TCGv_i32 temp = tcg_constant_i32(con);
1384 gen_addc_CC(ret, r1, temp);
1385 }
1386
1387 static void gen_cond_add(TCGCond cond,
1388 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3, TCGv_i32 r4)
1389 {
1390 TCGv_i32 temp = tcg_temp_new_i32();
1391 TCGv_i32 temp2 = tcg_temp_new_i32();
1392 TCGv_i32 result = tcg_temp_new_i32();
1393 TCGv_i32 mask = tcg_temp_new_i32();
1394 TCGv_i32 t0 = tcg_constant_i32(0);
1395
1396 /* create mask for sticky bits */
1397 tcg_gen_setcond_i32(cond, mask, r4, t0);
1398 tcg_gen_shli_i32(mask, mask, 31);
1399
1400 tcg_gen_add_i32(result, r1, r2);
1401 /* Calc PSW_V */
1402 tcg_gen_xor_i32(temp, result, r1);
1403 tcg_gen_xor_i32(temp2, r1, r2);
1404 tcg_gen_andc_i32(temp, temp, temp2);
1405 tcg_gen_movcond_i32(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1406 /* Set PSW_SV */
1407 tcg_gen_and_i32(temp, temp, mask);
1408 tcg_gen_or_i32(cpu_PSW_SV, temp, cpu_PSW_SV);
1409 /* calc AV bit */
1410 tcg_gen_add_i32(temp, result, result);
1411 tcg_gen_xor_i32(temp, temp, result);
1412 tcg_gen_movcond_i32(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1413 /* calc SAV bit */
1414 tcg_gen_and_i32(temp, temp, mask);
1415 tcg_gen_or_i32(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1416 /* write back result */
1417 tcg_gen_movcond_i32(cond, r3, r4, t0, result, r1);
1418 }
1419
1420 static void gen_condi_add(TCGCond cond,
1421 TCGv_i32 r1, int32_t r2, TCGv_i32 r3, TCGv_i32 r4)
1422 {
1423 TCGv_i32 temp = tcg_constant_i32(r2);
1424 gen_cond_add(cond, r1, temp, r3, r4);
1425 }
1426
1427 static void gen_sub_d(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
1428 {
1429 TCGv_i32 temp = tcg_temp_new_i32();
1430 TCGv_i32 result = tcg_temp_new_i32();
1431
1432 tcg_gen_sub_i32(result, r1, r2);
1433 /* calc V bit */
1434 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
1435 tcg_gen_xor_i32(temp, r1, r2);
1436 tcg_gen_and_i32(cpu_PSW_V, cpu_PSW_V, temp);
1437 /* calc SV bit */
1438 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1439 /* Calc AV bit */
1440 tcg_gen_add_i32(cpu_PSW_AV, result, result);
1441 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
1442 /* calc SAV bit */
1443 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1444 /* write back result */
1445 tcg_gen_mov_i32(ret, result);
1446 }
1447
1448 static void gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
1449 {
1450 TCGv_i32 temp = tcg_temp_new_i32();
1451 TCGv_i64 t0 = tcg_temp_new_i64();
1452 TCGv_i64 t1 = tcg_temp_new_i64();
1453 TCGv_i64 result = tcg_temp_new_i64();
1454
1455 tcg_gen_sub_i64(result, r1, r2);
1456 /* calc v bit */
1457 tcg_gen_xor_i64(t1, result, r1);
1458 tcg_gen_xor_i64(t0, r1, r2);
1459 tcg_gen_and_i64(t1, t1, t0);
1460 tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
1461 /* calc SV bit */
1462 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1463 /* calc AV/SAV bits */
1464 tcg_gen_extrh_i64_i32(temp, result);
1465 tcg_gen_add_i32(cpu_PSW_AV, temp, temp);
1466 tcg_gen_xor_i32(cpu_PSW_AV, temp, cpu_PSW_AV);
1467 /* calc SAV */
1468 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1469 /* write back result */
1470 tcg_gen_mov_i64(ret, result);
1471 }
1472
1473 static void gen_sub_CC(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
1474 {
1475 TCGv_i32 result = tcg_temp_new_i32();
1476 TCGv_i32 temp = tcg_temp_new_i32();
1477
1478 tcg_gen_sub_i32(result, r1, r2);
1479 /* calc C bit */
1480 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_PSW_C, r1, r2);
1481 /* calc V bit */
1482 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
1483 tcg_gen_xor_i32(temp, r1, r2);
1484 tcg_gen_and_i32(cpu_PSW_V, cpu_PSW_V, temp);
1485 /* calc SV bit */
1486 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1487 /* Calc AV bit */
1488 tcg_gen_add_i32(cpu_PSW_AV, result, result);
1489 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
1490 /* calc SAV bit */
1491 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1492 /* write back result */
1493 tcg_gen_mov_i32(ret, result);
1494 }
1495
1496 static void gen_subc_CC(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
1497 {
1498 TCGv_i32 temp = tcg_temp_new_i32();
1499 tcg_gen_not_i32(temp, r2);
1500 gen_addc_CC(ret, r1, temp);
1501 }
1502
1503 static void gen_cond_sub(TCGCond cond,
1504 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3, TCGv_i32 r4)
1505 {
1506 TCGv_i32 temp = tcg_temp_new_i32();
1507 TCGv_i32 temp2 = tcg_temp_new_i32();
1508 TCGv_i32 result = tcg_temp_new_i32();
1509 TCGv_i32 mask = tcg_temp_new_i32();
1510 TCGv_i32 t0 = tcg_constant_i32(0);
1511
1512 /* create mask for sticky bits */
1513 tcg_gen_setcond_i32(cond, mask, r4, t0);
1514 tcg_gen_shli_i32(mask, mask, 31);
1515
1516 tcg_gen_sub_i32(result, r1, r2);
1517 /* Calc PSW_V */
1518 tcg_gen_xor_i32(temp, result, r1);
1519 tcg_gen_xor_i32(temp2, r1, r2);
1520 tcg_gen_and_i32(temp, temp, temp2);
1521 tcg_gen_movcond_i32(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1522 /* Set PSW_SV */
1523 tcg_gen_and_i32(temp, temp, mask);
1524 tcg_gen_or_i32(cpu_PSW_SV, temp, cpu_PSW_SV);
1525 /* calc AV bit */
1526 tcg_gen_add_i32(temp, result, result);
1527 tcg_gen_xor_i32(temp, temp, result);
1528 tcg_gen_movcond_i32(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1529 /* calc SAV bit */
1530 tcg_gen_and_i32(temp, temp, mask);
1531 tcg_gen_or_i32(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1532 /* write back result */
1533 tcg_gen_movcond_i32(cond, r3, r4, t0, result, r1);
1534 }
1535
1536 static void gen_msub_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1537 TCGv_i32 r1_low, TCGv_i32 r1_high,
1538 TCGv_i32 r2, TCGv_i32 r3,
1539 uint32_t n, uint32_t mode)
1540 {
1541 TCGv_i32 t_n = tcg_constant_i32(n);
1542 TCGv_i32 temp = tcg_temp_new_i32();
1543 TCGv_i32 temp2 = tcg_temp_new_i32();
1544 TCGv_i64 temp64 = tcg_temp_new_i64();
1545 switch (mode) {
1546 case MODE_LL:
1547 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1548 break;
1549 case MODE_LU:
1550 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1551 break;
1552 case MODE_UL:
1553 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
1554 break;
1555 case MODE_UU:
1556 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
1557 break;
1558 }
1559 tcg_gen_extr_i64_i32(temp, temp2, temp64);
1560 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
1561 tcg_gen_sub_tl, tcg_gen_sub_tl);
1562 }
1563
1564 static void gen_msubs_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1565 TCGv_i32 r1_low, TCGv_i32 r1_high,
1566 TCGv_i32 r2, TCGv_i32 r3,
1567 uint32_t n, uint32_t mode)
1568 {
1569 TCGv_i32 t_n = tcg_constant_i32(n);
1570 TCGv_i32 temp = tcg_temp_new_i32();
1571 TCGv_i32 temp2 = tcg_temp_new_i32();
1572 TCGv_i32 temp3 = tcg_temp_new_i32();
1573 TCGv_i64 temp64 = tcg_temp_new_i64();
1574
1575 switch (mode) {
1576 case MODE_LL:
1577 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1578 break;
1579 case MODE_LU:
1580 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1581 break;
1582 case MODE_UL:
1583 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
1584 break;
1585 case MODE_UU:
1586 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
1587 break;
1588 }
1589 tcg_gen_extr_i64_i32(temp, temp2, temp64);
1590 gen_subs(ret_low, r1_low, temp);
1591 tcg_gen_mov_i32(temp, cpu_PSW_V);
1592 tcg_gen_mov_i32(temp3, cpu_PSW_AV);
1593 gen_subs(ret_high, r1_high, temp2);
1594 /* combine v bits */
1595 tcg_gen_or_i32(cpu_PSW_V, cpu_PSW_V, temp);
1596 /* combine av bits */
1597 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp3);
1598 }
1599
1600 static void gen_msubm_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1601 TCGv_i32 r1_low, TCGv_i32 r1_high,
1602 TCGv_i32 r2, TCGv_i32 r3,
1603 uint32_t n, uint32_t mode)
1604 {
1605 TCGv_i32 t_n = tcg_constant_i32(n);
1606 TCGv_i64 temp64 = tcg_temp_new_i64();
1607 TCGv_i64 temp64_2 = tcg_temp_new_i64();
1608 TCGv_i64 temp64_3 = tcg_temp_new_i64();
1609 switch (mode) {
1610 case MODE_LL:
1611 GEN_HELPER_LL(mulm_h, temp64, r2, r3, t_n);
1612 break;
1613 case MODE_LU:
1614 GEN_HELPER_LU(mulm_h, temp64, r2, r3, t_n);
1615 break;
1616 case MODE_UL:
1617 GEN_HELPER_UL(mulm_h, temp64, r2, r3, t_n);
1618 break;
1619 case MODE_UU:
1620 GEN_HELPER_UU(mulm_h, temp64, r2, r3, t_n);
1621 break;
1622 }
1623 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1624 gen_sub64_d(temp64_3, temp64_2, temp64);
1625 /* write back result */
1626 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
1627 }
1628
1629 static void gen_msubms_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1630 TCGv_i32 r1_low, TCGv_i32 r1_high,
1631 TCGv_i32 r2, TCGv_i32 r3,
1632 uint32_t n, uint32_t mode)
1633 {
1634 TCGv_i32 t_n = tcg_constant_i32(n);
1635 TCGv_i64 temp64 = tcg_temp_new_i64();
1636 TCGv_i64 temp64_2 = tcg_temp_new_i64();
1637 switch (mode) {
1638 case MODE_LL:
1639 GEN_HELPER_LL(mulm_h, temp64, r2, r3, t_n);
1640 break;
1641 case MODE_LU:
1642 GEN_HELPER_LU(mulm_h, temp64, r2, r3, t_n);
1643 break;
1644 case MODE_UL:
1645 GEN_HELPER_UL(mulm_h, temp64, r2, r3, t_n);
1646 break;
1647 case MODE_UU:
1648 GEN_HELPER_UU(mulm_h, temp64, r2, r3, t_n);
1649 break;
1650 }
1651 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1652 gen_helper_sub64_ssov(temp64, tcg_env, temp64_2, temp64);
1653 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
1654 }
1655
1656 static void gen_msubr64_h(TCGv_i32 ret,
1657 TCGv_i32 r1_low, TCGv_i32 r1_high,
1658 TCGv_i32 r2, TCGv_i32 r3,
1659 uint32_t n, uint32_t mode)
1660 {
1661 TCGv_i32 t_n = tcg_constant_i32(n);
1662 TCGv_i64 temp64 = tcg_temp_new_i64();
1663 switch (mode) {
1664 case MODE_LL:
1665 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1666 break;
1667 case MODE_LU:
1668 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1669 break;
1670 case MODE_UL:
1671 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
1672 break;
1673 case MODE_UU:
1674 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
1675 break;
1676 }
1677 gen_helper_subr_h(ret, tcg_env, temp64, r1_low, r1_high);
1678 }
1679
1680 static void gen_msubr32_h(TCGv_i32 ret,
1681 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
1682 uint32_t n, uint32_t mode)
1683 {
1684 TCGv_i32 temp = tcg_temp_new_i32();
1685 TCGv_i32 temp2 = tcg_temp_new_i32();
1686
1687 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
1688 tcg_gen_shli_i32(temp, r1, 16);
1689 gen_msubr64_h(ret, temp, temp2, r2, r3, n, mode);
1690 }
1691
1692 static void gen_msubr64s_h(TCGv_i32 ret,
1693 TCGv_i32 r1_low, TCGv_i32 r1_high,
1694 TCGv_i32 r2, TCGv_i32 r3,
1695 uint32_t n, uint32_t mode)
1696 {
1697 TCGv_i32 t_n = tcg_constant_i32(n);
1698 TCGv_i64 temp64 = tcg_temp_new_i64();
1699 switch (mode) {
1700 case MODE_LL:
1701 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1702 break;
1703 case MODE_LU:
1704 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1705 break;
1706 case MODE_UL:
1707 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
1708 break;
1709 case MODE_UU:
1710 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
1711 break;
1712 }
1713 gen_helper_subr_h_ssov(ret, tcg_env, temp64, r1_low, r1_high);
1714 }
1715
1716 static void gen_msubr32s_h(TCGv_i32 ret,
1717 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
1718 uint32_t n, uint32_t mode)
1719 {
1720 TCGv_i32 temp = tcg_temp_new_i32();
1721 TCGv_i32 temp2 = tcg_temp_new_i32();
1722
1723 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
1724 tcg_gen_shli_i32(temp, r1, 16);
1725 gen_msubr64s_h(ret, temp, temp2, r2, r3, n, mode);
1726 }
1727
1728 static void gen_msubr_q(TCGv_i32 ret,
1729 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3, uint32_t n)
1730 {
1731 TCGv_i32 temp = tcg_constant_i32(n);
1732 gen_helper_msubr_q(ret, tcg_env, r1, r2, r3, temp);
1733 }
1734
1735 static void gen_msubrs_q(TCGv_i32 ret,
1736 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3, uint32_t n)
1737 {
1738 TCGv_i32 temp = tcg_constant_i32(n);
1739 gen_helper_msubr_q_ssov(ret, tcg_env, r1, r2, r3, temp);
1740 }
1741
1742 static void gen_msub32_q(TCGv_i32 ret,
1743 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1744 uint32_t n, uint32_t up_shift)
1745 {
1746 TCGv_i32 temp3 = tcg_temp_new_i32();
1747 TCGv_i64 t1 = tcg_temp_new_i64();
1748 TCGv_i64 t2 = tcg_temp_new_i64();
1749 TCGv_i64 t3 = tcg_temp_new_i64();
1750 TCGv_i64 t4 = tcg_temp_new_i64();
1751
1752 tcg_gen_ext_i32_i64(t2, arg2);
1753 tcg_gen_ext_i32_i64(t3, arg3);
1754
1755 tcg_gen_mul_i64(t2, t2, t3);
1756
1757 tcg_gen_ext_i32_i64(t1, arg1);
1758 /* if we shift part of the fraction out, we need to round up */
1759 tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
1760 tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
1761 tcg_gen_sari_i64(t2, t2, up_shift - n);
1762 tcg_gen_add_i64(t2, t2, t4);
1763
1764 tcg_gen_sub_i64(t3, t1, t2);
1765 tcg_gen_extrl_i64_i32(temp3, t3);
1766 /* calc v bit */
1767 tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1768 tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1769 tcg_gen_or_i64(t1, t1, t2);
1770 tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1771 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
1772 /* Calc SV bit */
1773 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1774 /* Calc AV/SAV bits */
1775 tcg_gen_add_i32(cpu_PSW_AV, temp3, temp3);
1776 tcg_gen_xor_i32(cpu_PSW_AV, temp3, cpu_PSW_AV);
1777 /* calc SAV */
1778 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1779 /* write back result */
1780 tcg_gen_mov_i32(ret, temp3);
1781 }
1782
1783 static void gen_m16sub32_q(TCGv_i32 ret,
1784 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1785 uint32_t n)
1786 {
1787 TCGv_i32 temp = tcg_temp_new_i32();
1788 TCGv_i32 temp2 = tcg_temp_new_i32();
1789 if (n == 0) {
1790 tcg_gen_mul_i32(temp, arg2, arg3);
1791 } else { /* n is expected to be 1 */
1792 tcg_gen_mul_i32(temp, arg2, arg3);
1793 tcg_gen_shli_i32(temp, temp, 1);
1794 /* catch special case r1 = r2 = 0x8000 */
1795 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1796 tcg_gen_sub_i32(temp, temp, temp2);
1797 }
1798 gen_sub_d(ret, arg1, temp);
1799 }
1800
1801 static void gen_m16subs32_q(TCGv_i32 ret,
1802 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1803 uint32_t n)
1804 {
1805 TCGv_i32 temp = tcg_temp_new_i32();
1806 TCGv_i32 temp2 = tcg_temp_new_i32();
1807 if (n == 0) {
1808 tcg_gen_mul_i32(temp, arg2, arg3);
1809 } else { /* n is expected to be 1 */
1810 tcg_gen_mul_i32(temp, arg2, arg3);
1811 tcg_gen_shli_i32(temp, temp, 1);
1812 /* catch special case r1 = r2 = 0x8000 */
1813 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1814 tcg_gen_sub_i32(temp, temp, temp2);
1815 }
1816 gen_subs(ret, arg1, temp);
1817 }
1818
1819 static void gen_m16sub64_q(TCGv_i32 rl, TCGv_i32 rh,
1820 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1821 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1822 {
1823 TCGv_i32 temp = tcg_temp_new_i32();
1824 TCGv_i32 temp2 = tcg_temp_new_i32();
1825 TCGv_i64 t1 = tcg_temp_new_i64();
1826 TCGv_i64 t2 = tcg_temp_new_i64();
1827 TCGv_i64 t3 = tcg_temp_new_i64();
1828
1829 if (n == 0) {
1830 tcg_gen_mul_i32(temp, arg2, arg3);
1831 } else { /* n is expected to be 1 */
1832 tcg_gen_mul_i32(temp, arg2, arg3);
1833 tcg_gen_shli_i32(temp, temp, 1);
1834 /* catch special case r1 = r2 = 0x8000 */
1835 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1836 tcg_gen_sub_i32(temp, temp, temp2);
1837 }
1838 tcg_gen_ext_i32_i64(t2, temp);
1839 tcg_gen_shli_i64(t2, t2, 16);
1840 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1841 gen_sub64_d(t3, t1, t2);
1842 /* write back result */
1843 tcg_gen_extr_i64_i32(rl, rh, t3);
1844 }
1845
1846 static void gen_m16subs64_q(TCGv_i32 rl, TCGv_i32 rh,
1847 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1848 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1849 {
1850 TCGv_i32 temp = tcg_temp_new_i32();
1851 TCGv_i32 temp2 = tcg_temp_new_i32();
1852 TCGv_i64 t1 = tcg_temp_new_i64();
1853 TCGv_i64 t2 = tcg_temp_new_i64();
1854
1855 if (n == 0) {
1856 tcg_gen_mul_i32(temp, arg2, arg3);
1857 } else { /* n is expected to be 1 */
1858 tcg_gen_mul_i32(temp, arg2, arg3);
1859 tcg_gen_shli_i32(temp, temp, 1);
1860 /* catch special case r1 = r2 = 0x8000 */
1861 tcg_gen_setcondi_i32(TCG_COND_EQ, temp2, temp, 0x80000000);
1862 tcg_gen_sub_i32(temp, temp, temp2);
1863 }
1864 tcg_gen_ext_i32_i64(t2, temp);
1865 tcg_gen_shli_i64(t2, t2, 16);
1866 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1867
1868 gen_helper_sub64_ssov(t1, tcg_env, t1, t2);
1869 tcg_gen_extr_i64_i32(rl, rh, t1);
1870 }
1871
1872 static void gen_msub64_q(TCGv_i32 rl, TCGv_i32 rh,
1873 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1874 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1875 {
1876 TCGv_i64 t1 = tcg_temp_new_i64();
1877 TCGv_i64 t2 = tcg_temp_new_i64();
1878 TCGv_i64 t3 = tcg_temp_new_i64();
1879 TCGv_i64 t4 = tcg_temp_new_i64();
1880 TCGv_i32 temp, temp2;
1881
1882 tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1883 tcg_gen_ext_i32_i64(t2, arg2);
1884 tcg_gen_ext_i32_i64(t3, arg3);
1885
1886 tcg_gen_mul_i64(t2, t2, t3);
1887 if (n != 0) {
1888 tcg_gen_shli_i64(t2, t2, 1);
1889 }
1890 tcg_gen_sub_i64(t4, t1, t2);
1891 /* calc v bit */
1892 tcg_gen_xor_i64(t3, t4, t1);
1893 tcg_gen_xor_i64(t2, t1, t2);
1894 tcg_gen_and_i64(t3, t3, t2);
1895 tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
1896 /* We produce an overflow on the host if the mul before was
1897 (0x80000000 * 0x80000000) << 1). If this is the
1898 case, we negate the ovf. */
1899 if (n == 1) {
1900 temp = tcg_temp_new_i32();
1901 temp2 = tcg_temp_new_i32();
1902 tcg_gen_setcondi_i32(TCG_COND_EQ, temp, arg2, 0x80000000);
1903 tcg_gen_setcond_i32(TCG_COND_EQ, temp2, arg2, arg3);
1904 tcg_gen_and_i32(temp, temp, temp2);
1905 tcg_gen_shli_i32(temp, temp, 31);
1906 /* negate v bit, if special condition */
1907 tcg_gen_xor_i32(cpu_PSW_V, cpu_PSW_V, temp);
1908 }
1909 /* write back result */
1910 tcg_gen_extr_i64_i32(rl, rh, t4);
1911 /* Calc SV bit */
1912 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1913 /* Calc AV/SAV bits */
1914 tcg_gen_add_i32(cpu_PSW_AV, rh, rh);
1915 tcg_gen_xor_i32(cpu_PSW_AV, rh, cpu_PSW_AV);
1916 /* calc SAV */
1917 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1918 }
1919
1920 static void gen_msubs32_q(TCGv_i32 ret,
1921 TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3,
1922 uint32_t n, uint32_t up_shift)
1923 {
1924 TCGv_i64 t1 = tcg_temp_new_i64();
1925 TCGv_i64 t2 = tcg_temp_new_i64();
1926 TCGv_i64 t3 = tcg_temp_new_i64();
1927 TCGv_i64 t4 = tcg_temp_new_i64();
1928
1929 tcg_gen_ext_i32_i64(t1, arg1);
1930 tcg_gen_ext_i32_i64(t2, arg2);
1931 tcg_gen_ext_i32_i64(t3, arg3);
1932
1933 tcg_gen_mul_i64(t2, t2, t3);
1934 /* if we shift part of the fraction out, we need to round up */
1935 tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
1936 tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
1937 tcg_gen_sari_i64(t3, t2, up_shift - n);
1938 tcg_gen_add_i64(t3, t3, t4);
1939
1940 gen_helper_msub32_q_sub_ssov(ret, tcg_env, t1, t3);
1941 }
1942
1943 static void gen_msubs64_q(TCGv_i32 rl, TCGv_i32 rh,
1944 TCGv_i32 arg1_low, TCGv_i32 arg1_high,
1945 TCGv_i32 arg2, TCGv_i32 arg3, uint32_t n)
1946 {
1947 TCGv_i64 r1 = tcg_temp_new_i64();
1948 TCGv_i32 t_n = tcg_constant_i32(n);
1949
1950 tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
1951 gen_helper_msub64_q_ssov(r1, tcg_env, r1, arg2, arg3, t_n);
1952 tcg_gen_extr_i64_i32(rl, rh, r1);
1953 }
1954
1955 static void gen_msubad_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1956 TCGv_i32 r1_low, TCGv_i32 r1_high,
1957 TCGv_i32 r2, TCGv_i32 r3,
1958 uint32_t n, uint32_t mode)
1959 {
1960 TCGv_i32 t_n = tcg_constant_i32(n);
1961 TCGv_i32 temp = tcg_temp_new_i32();
1962 TCGv_i32 temp2 = tcg_temp_new_i32();
1963 TCGv_i64 temp64 = tcg_temp_new_i64();
1964 switch (mode) {
1965 case MODE_LL:
1966 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1967 break;
1968 case MODE_LU:
1969 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1970 break;
1971 case MODE_UL:
1972 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
1973 break;
1974 case MODE_UU:
1975 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
1976 break;
1977 }
1978 tcg_gen_extr_i64_i32(temp, temp2, temp64);
1979 gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
1980 tcg_gen_add_tl, tcg_gen_sub_tl);
1981 }
1982
1983 static void gen_msubadm_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
1984 TCGv_i32 r1_low, TCGv_i32 r1_high,
1985 TCGv_i32 r2, TCGv_i32 r3,
1986 uint32_t n, uint32_t mode)
1987 {
1988 TCGv_i32 t_n = tcg_constant_i32(n);
1989 TCGv_i64 temp64 = tcg_temp_new_i64();
1990 TCGv_i64 temp64_2 = tcg_temp_new_i64();
1991 TCGv_i64 temp64_3 = tcg_temp_new_i64();
1992 switch (mode) {
1993 case MODE_LL:
1994 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
1995 break;
1996 case MODE_LU:
1997 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
1998 break;
1999 case MODE_UL:
2000 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
2001 break;
2002 case MODE_UU:
2003 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
2004 break;
2005 }
2006 tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
2007 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2008 tcg_gen_ext32s_i64(temp64, temp64); /* low */
2009 tcg_gen_sub_i64(temp64, temp64_2, temp64);
2010 tcg_gen_shli_i64(temp64, temp64, 16);
2011
2012 gen_sub64_d(temp64_2, temp64_3, temp64);
2013 /* write back result */
2014 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
2015 }
2016
2017 static void gen_msubadr32_h(TCGv_i32 ret,
2018 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
2019 uint32_t n, uint32_t mode)
2020 {
2021 TCGv_i32 t_n = tcg_constant_i32(n);
2022 TCGv_i32 temp = tcg_temp_new_i32();
2023 TCGv_i32 temp2 = tcg_temp_new_i32();
2024 TCGv_i64 temp64 = tcg_temp_new_i64();
2025 switch (mode) {
2026 case MODE_LL:
2027 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
2028 break;
2029 case MODE_LU:
2030 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
2031 break;
2032 case MODE_UL:
2033 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
2034 break;
2035 case MODE_UU:
2036 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
2037 break;
2038 }
2039 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
2040 tcg_gen_shli_i32(temp, r1, 16);
2041 gen_helper_subadr_h(ret, tcg_env, temp64, temp, temp2);
2042 }
2043
2044 static void gen_msubads_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
2045 TCGv_i32 r1_low, TCGv_i32 r1_high,
2046 TCGv_i32 r2, TCGv_i32 r3,
2047 uint32_t n, uint32_t mode)
2048 {
2049 TCGv_i32 t_n = tcg_constant_i32(n);
2050 TCGv_i32 temp = tcg_temp_new_i32();
2051 TCGv_i32 temp2 = tcg_temp_new_i32();
2052 TCGv_i32 temp3 = tcg_temp_new_i32();
2053 TCGv_i64 temp64 = tcg_temp_new_i64();
2054
2055 switch (mode) {
2056 case MODE_LL:
2057 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
2058 break;
2059 case MODE_LU:
2060 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
2061 break;
2062 case MODE_UL:
2063 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
2064 break;
2065 case MODE_UU:
2066 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
2067 break;
2068 }
2069 tcg_gen_extr_i64_i32(temp, temp2, temp64);
2070 gen_adds(ret_low, r1_low, temp);
2071 tcg_gen_mov_i32(temp, cpu_PSW_V);
2072 tcg_gen_mov_i32(temp3, cpu_PSW_AV);
2073 gen_subs(ret_high, r1_high, temp2);
2074 /* combine v bits */
2075 tcg_gen_or_i32(cpu_PSW_V, cpu_PSW_V, temp);
2076 /* combine av bits */
2077 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp3);
2078 }
2079
2080 static void gen_msubadms_h(TCGv_i32 ret_low, TCGv_i32 ret_high,
2081 TCGv_i32 r1_low, TCGv_i32 r1_high,
2082 TCGv_i32 r2, TCGv_i32 r3,
2083 uint32_t n, uint32_t mode)
2084 {
2085 TCGv_i32 t_n = tcg_constant_i32(n);
2086 TCGv_i64 temp64 = tcg_temp_new_i64();
2087 TCGv_i64 temp64_2 = tcg_temp_new_i64();
2088
2089 switch (mode) {
2090 case MODE_LL:
2091 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
2092 break;
2093 case MODE_LU:
2094 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
2095 break;
2096 case MODE_UL:
2097 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
2098 break;
2099 case MODE_UU:
2100 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
2101 break;
2102 }
2103 tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2104 tcg_gen_ext32s_i64(temp64, temp64); /* low */
2105 tcg_gen_sub_i64(temp64, temp64_2, temp64);
2106 tcg_gen_shli_i64(temp64, temp64, 16);
2107 tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
2108
2109 gen_helper_sub64_ssov(temp64, tcg_env, temp64_2, temp64);
2110 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2111 }
2112
2113 static void gen_msubadr32s_h(TCGv_i32 ret,
2114 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 r3,
2115 uint32_t n, uint32_t mode)
2116 {
2117 TCGv_i32 t_n = tcg_constant_i32(n);
2118 TCGv_i32 temp = tcg_temp_new_i32();
2119 TCGv_i32 temp2 = tcg_temp_new_i32();
2120 TCGv_i64 temp64 = tcg_temp_new_i64();
2121 switch (mode) {
2122 case MODE_LL:
2123 GEN_HELPER_LL(mul_h, temp64, r2, r3, t_n);
2124 break;
2125 case MODE_LU:
2126 GEN_HELPER_LU(mul_h, temp64, r2, r3, t_n);
2127 break;
2128 case MODE_UL:
2129 GEN_HELPER_UL(mul_h, temp64, r2, r3, t_n);
2130 break;
2131 case MODE_UU:
2132 GEN_HELPER_UU(mul_h, temp64, r2, r3, t_n);
2133 break;
2134 }
2135 tcg_gen_andi_i32(temp2, r1, 0xffff0000);
2136 tcg_gen_shli_i32(temp, r1, 16);
2137 gen_helper_subadr_h_ssov(ret, tcg_env, temp64, temp, temp2);
2138 }
2139
2140 static void gen_abs(TCGv_i32 ret, TCGv_i32 r1)
2141 {
2142 tcg_gen_abs_i32(ret, r1);
2143 /* overflow can only happen, if r1 = 0x80000000 */
2144 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
2145 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
2146 /* calc SV bit */
2147 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2148 /* Calc AV bit */
2149 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
2150 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
2151 /* calc SAV bit */
2152 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2153 }
2154
2155 static void gen_absdif(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2156 {
2157 TCGv_i32 temp = tcg_temp_new_i32();
2158 TCGv_i32 result = tcg_temp_new_i32();
2159
2160 tcg_gen_sub_i32(result, r1, r2);
2161 tcg_gen_sub_i32(temp, r2, r1);
2162 tcg_gen_movcond_i32(TCG_COND_GT, result, r1, r2, result, temp);
2163
2164 /* calc V bit */
2165 tcg_gen_xor_i32(cpu_PSW_V, result, r1);
2166 tcg_gen_xor_i32(temp, result, r2);
2167 tcg_gen_movcond_i32(TCG_COND_GT, cpu_PSW_V, r1, r2, cpu_PSW_V, temp);
2168 tcg_gen_xor_i32(temp, r1, r2);
2169 tcg_gen_and_i32(cpu_PSW_V, cpu_PSW_V, temp);
2170 /* calc SV bit */
2171 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2172 /* Calc AV bit */
2173 tcg_gen_add_i32(cpu_PSW_AV, result, result);
2174 tcg_gen_xor_i32(cpu_PSW_AV, result, cpu_PSW_AV);
2175 /* calc SAV bit */
2176 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2177 /* write back result */
2178 tcg_gen_mov_i32(ret, result);
2179 }
2180
2181 static void gen_absdifi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2182 {
2183 TCGv_i32 temp = tcg_constant_i32(con);
2184 gen_absdif(ret, r1, temp);
2185 }
2186
2187 static void gen_absdifsi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2188 {
2189 TCGv_i32 temp = tcg_constant_i32(con);
2190 gen_helper_absdif_ssov(ret, tcg_env, r1, temp);
2191 }
2192
2193 static void gen_mul_i32s(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2194 {
2195 TCGv_i32 high = tcg_temp_new_i32();
2196 TCGv_i32 low = tcg_temp_new_i32();
2197
2198 tcg_gen_muls2_i32(low, high, r1, r2);
2199 tcg_gen_mov_i32(ret, low);
2200 /* calc V bit */
2201 tcg_gen_sari_i32(low, low, 31);
2202 tcg_gen_setcond_i32(TCG_COND_NE, cpu_PSW_V, high, low);
2203 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
2204 /* calc SV bit */
2205 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2206 /* Calc AV bit */
2207 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
2208 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
2209 /* calc SAV bit */
2210 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2211 }
2212
2213 static void gen_muli_i32s(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2214 {
2215 TCGv_i32 temp = tcg_constant_i32(con);
2216 gen_mul_i32s(ret, r1, temp);
2217 }
2218
2219 static void gen_mul_i64s(TCGv_i32 ret_low, TCGv_i32 ret_high,
2220 TCGv_i32 r1, TCGv_i32 r2)
2221 {
2222 tcg_gen_muls2_i32(ret_low, ret_high, r1, r2);
2223 /* clear V bit */
2224 tcg_gen_movi_i32(cpu_PSW_V, 0);
2225 /* calc SV bit */
2226 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2227 /* Calc AV bit */
2228 tcg_gen_add_i32(cpu_PSW_AV, ret_high, ret_high);
2229 tcg_gen_xor_i32(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2230 /* calc SAV bit */
2231 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2232 }
2233
2234 static void gen_muli_i64s(TCGv_i32 ret_low, TCGv_i32 ret_high,
2235 TCGv_i32 r1, int32_t con)
2236 {
2237 TCGv_i32 temp = tcg_constant_i32(con);
2238 gen_mul_i64s(ret_low, ret_high, r1, temp);
2239 }
2240
2241 static void gen_mul_i64u(TCGv_i32 ret_low, TCGv_i32 ret_high,
2242 TCGv_i32 r1, TCGv_i32 r2)
2243 {
2244 tcg_gen_mulu2_i32(ret_low, ret_high, r1, r2);
2245 /* clear V bit */
2246 tcg_gen_movi_i32(cpu_PSW_V, 0);
2247 /* calc SV bit */
2248 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2249 /* Calc AV bit */
2250 tcg_gen_add_i32(cpu_PSW_AV, ret_high, ret_high);
2251 tcg_gen_xor_i32(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2252 /* calc SAV bit */
2253 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2254 }
2255
2256 static void gen_muli_i64u(TCGv_i32 ret_low, TCGv_i32 ret_high,
2257 TCGv_i32 r1, int32_t con)
2258 {
2259 TCGv_i32 temp = tcg_constant_i32(con);
2260 gen_mul_i64u(ret_low, ret_high, r1, temp);
2261 }
2262
2263 static void gen_mulsi_i32(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2264 {
2265 TCGv_i32 temp = tcg_constant_i32(con);
2266 gen_helper_mul_ssov(ret, tcg_env, r1, temp);
2267 }
2268
2269 static void gen_mulsui_i32(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2270 {
2271 TCGv_i32 temp = tcg_constant_i32(con);
2272 gen_helper_mul_suov(ret, tcg_env, r1, temp);
2273 }
2274
2275 /* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
2276 static void gen_maddsi_32(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
2277 {
2278 TCGv_i32 temp = tcg_constant_i32(con);
2279 gen_helper_madd32_ssov(ret, tcg_env, r1, r2, temp);
2280 }
2281
2282 static void gen_maddsui_32(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
2283 {
2284 TCGv_i32 temp = tcg_constant_i32(con);
2285 gen_helper_madd32_suov(ret, tcg_env, r1, r2, temp);
2286 }
2287
2288 static void gen_mul_q(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2,
2289 uint32_t n, uint32_t up_shift)
2290 {
2291 TCGv_i64 temp_64 = tcg_temp_new_i64();
2292 TCGv_i64 temp2_64 = tcg_temp_new_i64();
2293
2294 if (n == 0) {
2295 if (up_shift == 32) {
2296 tcg_gen_muls2_i32(rh, rl, arg1, arg2);
2297 } else if (up_shift == 16) {
2298 tcg_gen_ext_i32_i64(temp_64, arg1);
2299 tcg_gen_ext_i32_i64(temp2_64, arg2);
2300
2301 tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2302 tcg_gen_shri_i64(temp_64, temp_64, up_shift);
2303 tcg_gen_extr_i64_i32(rl, rh, temp_64);
2304 } else {
2305 tcg_gen_muls2_i32(rl, rh, arg1, arg2);
2306 }
2307 /* reset v bit */
2308 tcg_gen_movi_i32(cpu_PSW_V, 0);
2309 } else { /* n is expected to be 1 */
2310 tcg_gen_ext_i32_i64(temp_64, arg1);
2311 tcg_gen_ext_i32_i64(temp2_64, arg2);
2312
2313 tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2314
2315 if (up_shift == 0) {
2316 tcg_gen_shli_i64(temp_64, temp_64, 1);
2317 } else {
2318 tcg_gen_shri_i64(temp_64, temp_64, up_shift - 1);
2319 }
2320 tcg_gen_extr_i64_i32(rl, rh, temp_64);
2321 /* overflow only occurs if r1 = r2 = 0x8000 */
2322 if (up_shift == 0) {/* result is 64 bit */
2323 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_PSW_V, rh,
2324 0x80000000);
2325 } else { /* result is 32 bit */
2326 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_PSW_V, rl,
2327 0x80000000);
2328 }
2329 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
2330 /* calc sv overflow bit */
2331 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2332 }
2333 /* calc av overflow bit */
2334 if (up_shift == 0) {
2335 tcg_gen_add_i32(cpu_PSW_AV, rh, rh);
2336 tcg_gen_xor_i32(cpu_PSW_AV, rh, cpu_PSW_AV);
2337 } else {
2338 tcg_gen_add_i32(cpu_PSW_AV, rl, rl);
2339 tcg_gen_xor_i32(cpu_PSW_AV, rl, cpu_PSW_AV);
2340 }
2341 /* calc sav overflow bit */
2342 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2343 }
2344
2345 static void gen_mul_q_16(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, uint32_t n)
2346 {
2347 TCGv_i32 temp = tcg_temp_new_i32();
2348 if (n == 0) {
2349 tcg_gen_mul_i32(ret, arg1, arg2);
2350 } else { /* n is expected to be 1 */
2351 tcg_gen_mul_i32(ret, arg1, arg2);
2352 tcg_gen_shli_i32(ret, ret, 1);
2353 /* catch special case r1 = r2 = 0x8000 */
2354 tcg_gen_setcondi_i32(TCG_COND_EQ, temp, ret, 0x80000000);
2355 tcg_gen_sub_i32(ret, ret, temp);
2356 }
2357 /* reset v bit */
2358 tcg_gen_movi_i32(cpu_PSW_V, 0);
2359 /* calc av overflow bit */
2360 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
2361 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
2362 /* calc sav overflow bit */
2363 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2364 }
2365
2366 static void gen_mulr_q(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, uint32_t n)
2367 {
2368 TCGv_i32 temp = tcg_temp_new_i32();
2369 if (n == 0) {
2370 tcg_gen_mul_i32(ret, arg1, arg2);
2371 tcg_gen_addi_i32(ret, ret, 0x8000);
2372 } else {
2373 tcg_gen_mul_i32(ret, arg1, arg2);
2374 tcg_gen_shli_i32(ret, ret, 1);
2375 tcg_gen_addi_i32(ret, ret, 0x8000);
2376 /* catch special case r1 = r2 = 0x8000 */
2377 tcg_gen_setcondi_i32(TCG_COND_EQ, temp, ret, 0x80008000);
2378 tcg_gen_muli_i32(temp, temp, 0x8001);
2379 tcg_gen_sub_i32(ret, ret, temp);
2380 }
2381 /* reset v bit */
2382 tcg_gen_movi_i32(cpu_PSW_V, 0);
2383 /* calc av overflow bit */
2384 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
2385 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
2386 /* calc sav overflow bit */
2387 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2388 /* cut halfword off */
2389 tcg_gen_andi_i32(ret, ret, 0xffff0000);
2390 }
2391
2392 static void gen_madds_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2393 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2394 TCGv_i32 r3)
2395 {
2396 TCGv_i64 temp64 = tcg_temp_new_i64();
2397 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2398 gen_helper_madd64_ssov(temp64, tcg_env, r1, temp64, r3);
2399 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2400 }
2401
2402 static void gen_maddsi_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2403 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2404 int32_t con)
2405 {
2406 TCGv_i32 temp = tcg_constant_i32(con);
2407 gen_madds_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2408 }
2409
2410 static void gen_maddsu_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2411 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2412 TCGv_i32 r3)
2413 {
2414 TCGv_i64 temp64 = tcg_temp_new_i64();
2415 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2416 gen_helper_madd64_suov(temp64, tcg_env, r1, temp64, r3);
2417 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2418 }
2419
2420 static void gen_maddsui_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2421 TCGv_i32 r1, TCGv_i32 r2_low,
2422 TCGv_i32 r2_high, int32_t con)
2423 {
2424 TCGv_i32 temp = tcg_constant_i32(con);
2425 gen_maddsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2426 }
2427
2428 static void gen_msubsi_32(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
2429 {
2430 TCGv_i32 temp = tcg_constant_i32(con);
2431 gen_helper_msub32_ssov(ret, tcg_env, r1, r2, temp);
2432 }
2433
2434 static void gen_msubsui_32(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2, int32_t con)
2435 {
2436 TCGv_i32 temp = tcg_constant_i32(con);
2437 gen_helper_msub32_suov(ret, tcg_env, r1, r2, temp);
2438 }
2439
2440 static void gen_msubs_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2441 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2442 TCGv_i32 r3)
2443 {
2444 TCGv_i64 temp64 = tcg_temp_new_i64();
2445 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2446 gen_helper_msub64_ssov(temp64, tcg_env, r1, temp64, r3);
2447 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2448 }
2449
2450 static void gen_msubsi_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2451 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2452 int32_t con)
2453 {
2454 TCGv_i32 temp = tcg_constant_i32(con);
2455 gen_msubs_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2456 }
2457
2458 static void gen_msubsu_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2459 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2460 TCGv_i32 r3)
2461 {
2462 TCGv_i64 temp64 = tcg_temp_new_i64();
2463 tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2464 gen_helper_msub64_suov(temp64, tcg_env, r1, temp64, r3);
2465 tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2466 }
2467
2468 static void gen_msubsui_64(TCGv_i32 ret_low, TCGv_i32 ret_high,
2469 TCGv_i32 r1, TCGv_i32 r2_low, TCGv_i32 r2_high,
2470 int32_t con)
2471 {
2472 TCGv_i32 temp = tcg_constant_i32(con);
2473 gen_msubsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2474 }
2475
2476 static void gen_saturate(TCGv_i32 ret, TCGv_i32 arg, int32_t up, int32_t low)
2477 {
2478 tcg_gen_smax_i32(ret, arg, tcg_constant_i32(low));
2479 tcg_gen_smin_i32(ret, ret, tcg_constant_i32(up));
2480 }
2481
2482 static void gen_saturate_u(TCGv_i32 ret, TCGv_i32 arg, int32_t up)
2483 {
2484 tcg_gen_umin_i32(ret, arg, tcg_constant_i32(up));
2485 }
2486
2487 static void gen_shi(TCGv_i32 ret, TCGv_i32 r1, int32_t shift_count)
2488 {
2489 if (shift_count == -32) {
2490 tcg_gen_movi_i32(ret, 0);
2491 } else if (shift_count >= 0) {
2492 tcg_gen_shli_i32(ret, r1, shift_count);
2493 } else {
2494 tcg_gen_shri_i32(ret, r1, -shift_count);
2495 }
2496 }
2497
2498 static void gen_sh_hi(TCGv_i32 ret, TCGv_i32 r1, int32_t shiftcount)
2499 {
2500 TCGv_i32 temp_low, temp_high;
2501
2502 if (shiftcount == -16) {
2503 tcg_gen_movi_i32(ret, 0);
2504 } else {
2505 temp_high = tcg_temp_new_i32();
2506 temp_low = tcg_temp_new_i32();
2507
2508 tcg_gen_andi_i32(temp_low, r1, 0xffff);
2509 tcg_gen_andi_i32(temp_high, r1, 0xffff0000);
2510 gen_shi(temp_low, temp_low, shiftcount);
2511 gen_shi(ret, temp_high, shiftcount);
2512 tcg_gen_deposit_i32(ret, ret, temp_low, 0, 16);
2513 }
2514 }
2515
2516 static void gen_shaci(TCGv_i32 ret, TCGv_i32 r1, int32_t shift_count)
2517 {
2518 uint32_t msk, msk_start;
2519 TCGv_i32 temp = tcg_temp_new_i32();
2520 TCGv_i32 temp2 = tcg_temp_new_i32();
2521
2522 if (shift_count == 0) {
2523 /* Clear PSW.C and PSW.V */
2524 tcg_gen_movi_i32(cpu_PSW_C, 0);
2525 tcg_gen_mov_i32(cpu_PSW_V, cpu_PSW_C);
2526 tcg_gen_mov_i32(ret, r1);
2527 } else if (shift_count == -32) {
2528 /* set PSW.C */
2529 tcg_gen_mov_i32(cpu_PSW_C, r1);
2530 /* fill ret completely with sign bit */
2531 tcg_gen_sari_i32(ret, r1, 31);
2532 /* clear PSW.V */
2533 tcg_gen_movi_i32(cpu_PSW_V, 0);
2534 } else if (shift_count > 0) {
2535 TCGv_i32 t_max = tcg_constant_i32(0x7FFFFFFF >> shift_count);
2536 TCGv_i32 t_min = tcg_constant_i32(((int32_t) -0x80000000) >> shift_count);
2537
2538 /* calc carry */
2539 msk_start = 32 - shift_count;
2540 msk = ((1 << shift_count) - 1) << msk_start;
2541 tcg_gen_andi_i32(cpu_PSW_C, r1, msk);
2542 /* calc v/sv bits */
2543 tcg_gen_setcond_i32(TCG_COND_GT, temp, r1, t_max);
2544 tcg_gen_setcond_i32(TCG_COND_LT, temp2, r1, t_min);
2545 tcg_gen_or_i32(cpu_PSW_V, temp, temp2);
2546 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
2547 /* calc sv */
2548 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_V, cpu_PSW_SV);
2549 /* do shift */
2550 tcg_gen_shli_i32(ret, r1, shift_count);
2551 } else {
2552 /* clear PSW.V */
2553 tcg_gen_movi_i32(cpu_PSW_V, 0);
2554 /* calc carry */
2555 msk = (1 << -shift_count) - 1;
2556 tcg_gen_andi_i32(cpu_PSW_C, r1, msk);
2557 /* do shift */
2558 tcg_gen_sari_i32(ret, r1, -shift_count);
2559 }
2560 /* calc av overflow bit */
2561 tcg_gen_add_i32(cpu_PSW_AV, ret, ret);
2562 tcg_gen_xor_i32(cpu_PSW_AV, ret, cpu_PSW_AV);
2563 /* calc sav overflow bit */
2564 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2565 }
2566
2567 static void gen_shas(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2568 {
2569 gen_helper_sha_ssov(ret, tcg_env, r1, r2);
2570 }
2571
2572 static void gen_shasi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2573 {
2574 TCGv_i32 temp = tcg_constant_i32(con);
2575 gen_shas(ret, r1, temp);
2576 }
2577
2578 static void gen_sha_hi(TCGv_i32 ret, TCGv_i32 r1, int32_t shift_count)
2579 {
2580 TCGv_i32 low, high;
2581
2582 if (shift_count == 0) {
2583 tcg_gen_mov_i32(ret, r1);
2584 } else if (shift_count > 0) {
2585 low = tcg_temp_new_i32();
2586 high = tcg_temp_new_i32();
2587
2588 tcg_gen_andi_i32(high, r1, 0xffff0000);
2589 tcg_gen_shli_i32(low, r1, shift_count);
2590 tcg_gen_shli_i32(ret, high, shift_count);
2591 tcg_gen_deposit_i32(ret, ret, low, 0, 16);
2592 } else {
2593 low = tcg_temp_new_i32();
2594 high = tcg_temp_new_i32();
2595
2596 tcg_gen_ext16s_i32(low, r1);
2597 tcg_gen_sari_i32(low, low, -shift_count);
2598 tcg_gen_sari_i32(ret, r1, -shift_count);
2599 tcg_gen_deposit_i32(ret, ret, low, 0, 16);
2600 }
2601 }
2602
2603 /* ret = {ret[30:0], (r1 cond r2)}; */
2604 static void gen_sh_cond(int cond, TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2605 {
2606 TCGv_i32 temp = tcg_temp_new_i32();
2607 TCGv_i32 temp2 = tcg_temp_new_i32();
2608
2609 tcg_gen_shli_i32(temp, ret, 1);
2610 tcg_gen_setcond_i32(cond, temp2, r1, r2);
2611 tcg_gen_or_i32(ret, temp, temp2);
2612 }
2613
2614 static void gen_sh_condi(int cond, TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2615 {
2616 TCGv_i32 temp = tcg_constant_i32(con);
2617 gen_sh_cond(cond, ret, r1, temp);
2618 }
2619
2620 static void gen_adds(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2621 {
2622 gen_helper_add_ssov(ret, tcg_env, r1, r2);
2623 }
2624
2625 static void gen_addsi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2626 {
2627 TCGv_i32 temp = tcg_constant_i32(con);
2628 gen_helper_add_ssov(ret, tcg_env, r1, temp);
2629 }
2630
2631 static void gen_addsui(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2632 {
2633 TCGv_i32 temp = tcg_constant_i32(con);
2634 gen_helper_add_suov(ret, tcg_env, r1, temp);
2635 }
2636
2637 static void gen_subs(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2638 {
2639 gen_helper_sub_ssov(ret, tcg_env, r1, r2);
2640 }
2641
2642 static void gen_subsu(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2)
2643 {
2644 gen_helper_sub_suov(ret, tcg_env, r1, r2);
2645 }
2646
2647 static void gen_bit_2op(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2,
2648 int pos1, int pos2,
2649 void(*op1)(TCGv_i32, TCGv_i32, TCGv_i32),
2650 void(*op2)(TCGv_i32, TCGv_i32, TCGv_i32))
2651 {
2652 TCGv_i32 temp1, temp2;
2653
2654 temp1 = tcg_temp_new_i32();
2655 temp2 = tcg_temp_new_i32();
2656
2657 tcg_gen_shri_i32(temp2, r2, pos2);
2658 tcg_gen_shri_i32(temp1, r1, pos1);
2659
2660 (*op1)(temp1, temp1, temp2);
2661 (*op2)(temp1 , ret, temp1);
2662
2663 tcg_gen_deposit_i32(ret, ret, temp1, 0, 1);
2664 }
2665
2666 /* ret = r1[pos1] op1 r2[pos2]; */
2667 static void gen_bit_1op(TCGv_i32 ret, TCGv_i32 r1, TCGv_i32 r2,
2668 int pos1, int pos2,
2669 void(*op1)(TCGv_i32, TCGv_i32, TCGv_i32))
2670 {
2671 TCGv_i32 temp1, temp2;
2672
2673 temp1 = tcg_temp_new_i32();
2674 temp2 = tcg_temp_new_i32();
2675
2676 tcg_gen_shri_i32(temp2, r2, pos2);
2677 tcg_gen_shri_i32(temp1, r1, pos1);
2678
2679 (*op1)(ret, temp1, temp2);
2680
2681 tcg_gen_andi_i32(ret, ret, 0x1);
2682 }
2683
2684 static void gen_accumulating_cond(int cond, TCGv_i32 ret,
2685 TCGv_i32 r1, TCGv_i32 r2,
2686 void(*op)(TCGv_i32, TCGv_i32, TCGv_i32))
2687 {
2688 TCGv_i32 temp = tcg_temp_new_i32();
2689 TCGv_i32 temp2 = tcg_temp_new_i32();
2690 /* temp = (arg1 cond arg2 )*/
2691 tcg_gen_setcond_i32(cond, temp, r1, r2);
2692 /* temp2 = ret[0]*/
2693 tcg_gen_andi_i32(temp2, ret, 0x1);
2694 /* temp = temp insn temp2 */
2695 (*op)(temp, temp, temp2);
2696 /* ret = {ret[31:1], temp} */
2697 tcg_gen_deposit_i32(ret, ret, temp, 0, 1);
2698 }
2699
2700 static void gen_accumulating_condi(int cond, TCGv_i32 ret, TCGv_i32 r1,
2701 int32_t con,
2702 void(*op)(TCGv_i32, TCGv_i32, TCGv_i32))
2703 {
2704 TCGv_i32 temp = tcg_constant_i32(con);
2705 gen_accumulating_cond(cond, ret, r1, temp, op);
2706 }
2707
2708 static void gen_eqany_bi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2709 {
2710 TCGv_i32 b0 = tcg_temp_new_i32();
2711 TCGv_i32 b1 = tcg_temp_new_i32();
2712 TCGv_i32 b2 = tcg_temp_new_i32();
2713 TCGv_i32 b3 = tcg_temp_new_i32();
2714
2715 /* byte 0 */
2716 tcg_gen_andi_i32(b0, r1, 0xff);
2717 tcg_gen_setcondi_i32(TCG_COND_EQ, b0, b0, con & 0xff);
2718
2719 /* byte 1 */
2720 tcg_gen_andi_i32(b1, r1, 0xff00);
2721 tcg_gen_setcondi_i32(TCG_COND_EQ, b1, b1, con & 0xff00);
2722
2723 /* byte 2 */
2724 tcg_gen_andi_i32(b2, r1, 0xff0000);
2725 tcg_gen_setcondi_i32(TCG_COND_EQ, b2, b2, con & 0xff0000);
2726
2727 /* byte 3 */
2728 tcg_gen_andi_i32(b3, r1, 0xff000000);
2729 tcg_gen_setcondi_i32(TCG_COND_EQ, b3, b3, con & 0xff000000);
2730
2731 /* combine them */
2732 tcg_gen_or_i32(ret, b0, b1);
2733 tcg_gen_or_i32(ret, ret, b2);
2734 tcg_gen_or_i32(ret, ret, b3);
2735 }
2736
2737 static void gen_eqany_hi(TCGv_i32 ret, TCGv_i32 r1, int32_t con)
2738 {
2739 TCGv_i32 h0 = tcg_temp_new_i32();
2740 TCGv_i32 h1 = tcg_temp_new_i32();
2741
2742 /* halfword 0 */
2743 tcg_gen_andi_i32(h0, r1, 0xffff);
2744 tcg_gen_setcondi_i32(TCG_COND_EQ, h0, h0, con & 0xffff);
2745
2746 /* halfword 1 */
2747 tcg_gen_andi_i32(h1, r1, 0xffff0000);
2748 tcg_gen_setcondi_i32(TCG_COND_EQ, h1, h1, con & 0xffff0000);
2749
2750 /* combine them */
2751 tcg_gen_or_i32(ret, h0, h1);
2752 }
2753
2754 /* mask = ((1 << width) -1) << pos;
2755 ret = (r1 & ~mask) | (r2 << pos) & mask); */
2756 static void gen_insert(TCGv_i32 ret,
2757 TCGv_i32 r1, TCGv_i32 r2, TCGv_i32 width, TCGv_i32 pos)
2758 {
2759 TCGv_i32 mask = tcg_temp_new_i32();
2760 TCGv_i32 temp = tcg_temp_new_i32();
2761 TCGv_i32 temp2 = tcg_temp_new_i32();
2762
2763 tcg_gen_shl_i32(mask, tcg_constant_i32(1), width);
2764 tcg_gen_subi_i32(mask, mask, 1);
2765 tcg_gen_shl_i32(mask, mask, pos);
2766
2767 tcg_gen_shl_i32(temp, r2, pos);
2768 tcg_gen_and_i32(temp, temp, mask);
2769 tcg_gen_andc_i32(temp2, r1, mask);
2770 tcg_gen_or_i32(ret, temp, temp2);
2771 }
2772
2773 static void gen_bsplit(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 r1)
2774 {
2775 TCGv_i64 temp = tcg_temp_new_i64();
2776
2777 gen_helper_bsplit(temp, r1);
2778 tcg_gen_extr_i64_i32(rl, rh, temp);
2779 }
2780
2781 static void gen_unpack(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 r1)
2782 {
2783 TCGv_i64 temp = tcg_temp_new_i64();
2784
2785 gen_helper_unpack(temp, r1);
2786 tcg_gen_extr_i64_i32(rl, rh, temp);
2787 }
2788
2789 static void gen_dvinit_b(DisasContext *ctx,
2790 TCGv_i32 rl, TCGv_i32 rh,
2791 TCGv_i32 r1, TCGv_i32 r2)
2792 {
2793 TCGv_i64 ret = tcg_temp_new_i64();
2794
2795 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
2796 gen_helper_dvinit_b_13(ret, tcg_env, r1, r2);
2797 } else {
2798 gen_helper_dvinit_b_131(ret, tcg_env, r1, r2);
2799 }
2800 tcg_gen_extr_i64_i32(rl, rh, ret);
2801 }
2802
2803 static void gen_dvinit_h(DisasContext *ctx,
2804 TCGv_i32 rl, TCGv_i32 rh,
2805 TCGv_i32 r1, TCGv_i32 r2)
2806 {
2807 TCGv_i64 ret = tcg_temp_new_i64();
2808
2809 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
2810 gen_helper_dvinit_h_13(ret, tcg_env, r1, r2);
2811 } else {
2812 gen_helper_dvinit_h_131(ret, tcg_env, r1, r2);
2813 }
2814 tcg_gen_extr_i64_i32(rl, rh, ret);
2815 }
2816
2817 static void gen_calc_usb_mul_h(TCGv_i32 arg_low, TCGv_i32 arg_high)
2818 {
2819 TCGv_i32 temp = tcg_temp_new_i32();
2820 /* calc AV bit */
2821 tcg_gen_add_i32(temp, arg_low, arg_low);
2822 tcg_gen_xor_i32(temp, temp, arg_low);
2823 tcg_gen_add_i32(cpu_PSW_AV, arg_high, arg_high);
2824 tcg_gen_xor_i32(cpu_PSW_AV, cpu_PSW_AV, arg_high);
2825 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp);
2826 /* calc SAV bit */
2827 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2828 tcg_gen_movi_i32(cpu_PSW_V, 0);
2829 }
2830
2831 static void gen_calc_usb_mulr_h(TCGv_i32 arg)
2832 {
2833 TCGv_i32 temp = tcg_temp_new_i32();
2834 /* calc AV bit */
2835 tcg_gen_add_i32(temp, arg, arg);
2836 tcg_gen_xor_i32(temp, temp, arg);
2837 tcg_gen_shli_i32(cpu_PSW_AV, temp, 16);
2838 tcg_gen_or_i32(cpu_PSW_AV, cpu_PSW_AV, temp);
2839 /* calc SAV bit */
2840 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2841 /* clear V bit */
2842 tcg_gen_movi_i32(cpu_PSW_V, 0);
2843 }
2844
2845 /* helpers for generating program flow micro-ops */
2846
2847 static void gen_save_pc(vaddr pc)
2848 {
2849 tcg_gen_movi_i32(cpu_PC, pc);
2850 }
2851
2852 static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_index, vaddr dest)
2853 {
2854 if (translator_use_goto_tb(&ctx->base, dest)) {
2855 tcg_gen_goto_tb(tb_slot_index);
2856 gen_save_pc(dest);
2857 tcg_gen_exit_tb(ctx->base.tb, tb_slot_index);
2858 } else {
2859 gen_save_pc(dest);
2860 tcg_gen_lookup_and_goto_ptr();
2861 }
2862 ctx->base.is_jmp = DISAS_NORETURN;
2863 }
2864
2865 static void generate_trap(DisasContext *ctx, int class, int tin)
2866 {
2867 TCGv_i32 classtemp = tcg_constant_i32(class);
2868 TCGv_i32 tintemp = tcg_constant_i32(tin);
2869
2870 gen_save_pc(ctx->base.pc_next);
2871 gen_helper_raise_exception_sync(tcg_env, classtemp, tintemp);
2872 ctx->base.is_jmp = DISAS_NORETURN;
2873 }
2874
2875 static void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv_i32 r1,
2876 TCGv_i32 r2, int16_t address)
2877 {
2878 TCGLabel *jumpLabel = gen_new_label();
2879 tcg_gen_brcond_i32(cond, r1, r2, jumpLabel);
2880
2881 gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
2882
2883 gen_set_label(jumpLabel);
2884 gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2);
2885 }
2886
2887 static void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv_i32 r1,
2888 int r2, int16_t address)
2889 {
2890 TCGv_i32 temp = tcg_constant_i32(r2);
2891 gen_branch_cond(ctx, cond, r1, temp, address);
2892 }
2893
2894 static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
2895 {
2896 TCGLabel *l1 = gen_new_label();
2897
2898 tcg_gen_subi_i32(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
2899 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
2900 gen_goto_tb(ctx, 1, ctx->base.pc_next + offset);
2901 gen_set_label(l1);
2902 gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
2903 }
2904
2905 static void gen_fcall_save_ctx(DisasContext *ctx)
2906 {
2907 TCGv_i32 temp = tcg_temp_new_i32();
2908
2909 tcg_gen_addi_i32(temp, cpu_gpr_a[10], -4);
2910 tcg_gen_qemu_st_i32(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
2911 tcg_gen_movi_i32(cpu_gpr_a[11], ctx->pc_succ_insn);
2912 tcg_gen_mov_i32(cpu_gpr_a[10], temp);
2913 }
2914
2915 static void gen_fret(DisasContext *ctx)
2916 {
2917 TCGv_i32 temp = tcg_temp_new_i32();
2918
2919 tcg_gen_andi_i32(temp, cpu_gpr_a[11], ~0x1);
2920 tcg_gen_qemu_ld_i32(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
2921 tcg_gen_addi_i32(cpu_gpr_a[10], cpu_gpr_a[10], 4);
2922 tcg_gen_mov_i32(cpu_PC, temp);
2923 ctx->base.is_jmp = DISAS_EXIT;
2924 }
2925
2926 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
2927 int r2 , int32_t constant , int32_t offset)
2928 {
2929 TCGv_i32 temp, temp2;
2930 int n;
2931
2932 switch (opc) {
2933 /* SB-format jumps */
2934 case OPC1_16_SB_J:
2935 case OPC1_32_B_J:
2936 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
2937 break;
2938 case OPC1_32_B_CALL:
2939 case OPC1_16_SB_CALL:
2940 gen_helper_1arg(call, ctx->pc_succ_insn);
2941 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
2942 break;
2943 case OPC1_16_SB_JZ:
2944 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
2945 break;
2946 case OPC1_16_SB_JNZ:
2947 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
2948 break;
2949 /* SBC-format jumps */
2950 case OPC1_16_SBC_JEQ:
2951 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
2952 break;
2953 case OPC1_16_SBC_JEQ2:
2954 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant,
2955 offset + 16);
2956 break;
2957 case OPC1_16_SBC_JNE:
2958 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
2959 break;
2960 case OPC1_16_SBC_JNE2:
2961 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15],
2962 constant, offset + 16);
2963 break;
2964 /* SBRN-format jumps */
2965 case OPC1_16_SBRN_JZ_T:
2966 temp = tcg_temp_new_i32();
2967 tcg_gen_andi_i32(temp, cpu_gpr_d[15], 0x1u << constant);
2968 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
2969 break;
2970 case OPC1_16_SBRN_JNZ_T:
2971 temp = tcg_temp_new_i32();
2972 tcg_gen_andi_i32(temp, cpu_gpr_d[15], 0x1u << constant);
2973 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
2974 break;
2975 /* SBR-format jumps */
2976 case OPC1_16_SBR_JEQ:
2977 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
2978 offset);
2979 break;
2980 case OPC1_16_SBR_JEQ2:
2981 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
2982 offset + 16);
2983 break;
2984 case OPC1_16_SBR_JNE:
2985 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
2986 offset);
2987 break;
2988 case OPC1_16_SBR_JNE2:
2989 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
2990 offset + 16);
2991 break;
2992 case OPC1_16_SBR_JNZ:
2993 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
2994 break;
2995 case OPC1_16_SBR_JNZ_A:
2996 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
2997 break;
2998 case OPC1_16_SBR_JGEZ:
2999 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
3000 break;
3001 case OPC1_16_SBR_JGTZ:
3002 gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
3003 break;
3004 case OPC1_16_SBR_JLEZ:
3005 gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
3006 break;
3007 case OPC1_16_SBR_JLTZ:
3008 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
3009 break;
3010 case OPC1_16_SBR_JZ:
3011 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
3012 break;
3013 case OPC1_16_SBR_JZ_A:
3014 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3015 break;
3016 case OPC1_16_SBR_LOOP:
3017 gen_loop(ctx, r1, offset * 2 - 32);
3018 break;
3019 /* SR-format jumps */
3020 case OPC1_16_SR_JI:
3021 tcg_gen_andi_i32(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
3022 ctx->base.is_jmp = DISAS_EXIT;
3023 break;
3024 case OPC2_32_SYS_RET:
3025 case OPC2_16_SR_RET:
3026 gen_helper_ret(tcg_env);
3027 ctx->base.is_jmp = DISAS_EXIT;
3028 break;
3029 /* B-format */
3030 case OPC1_32_B_CALLA:
3031 gen_helper_1arg(call, ctx->pc_succ_insn);
3032 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3033 break;
3034 case OPC1_32_B_FCALL:
3035 gen_fcall_save_ctx(ctx);
3036 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3037 break;
3038 case OPC1_32_B_FCALLA:
3039 gen_fcall_save_ctx(ctx);
3040 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3041 break;
3042 case OPC1_32_B_JLA:
3043 tcg_gen_movi_i32(cpu_gpr_a[11], ctx->pc_succ_insn);
3044 /* fall through */
3045 case OPC1_32_B_JA:
3046 gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3047 break;
3048 case OPC1_32_B_JL:
3049 tcg_gen_movi_i32(cpu_gpr_a[11], ctx->pc_succ_insn);
3050 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3051 break;
3052 /* BOL format */
3053 case OPCM_32_BRC_EQ_NEQ:
3054 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
3055 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
3056 } else {
3057 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
3058 }
3059 break;
3060 case OPCM_32_BRC_GE:
3061 if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
3062 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
3063 } else {
3064 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3065 gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
3066 offset);
3067 }
3068 break;
3069 case OPCM_32_BRC_JLT:
3070 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
3071 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
3072 } else {
3073 constant = MASK_OP_BRC_CONST4(ctx->opcode);
3074 gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
3075 offset);
3076 }
3077 break;
3078 case OPCM_32_BRC_JNE:
3079 temp = tcg_temp_new_i32();
3080 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
3081 tcg_gen_mov_i32(temp, cpu_gpr_d[r1]);
3082 /* subi is unconditional */
3083 tcg_gen_subi_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3084 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3085 } else {
3086 tcg_gen_mov_i32(temp, cpu_gpr_d[r1]);
3087 /* addi is unconditional */
3088 tcg_gen_addi_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3089 gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3090 }
3091 break;
3092 /* BRN format */
3093 case OPCM_32_BRN_JTT:
3094 n = MASK_OP_BRN_N(ctx->opcode);
3095
3096 temp = tcg_temp_new_i32();
3097 tcg_gen_andi_i32(temp, cpu_gpr_d[r1], (1 << n));
3098
3099 if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
3100 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3101 } else {
3102 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3103 }
3104 break;
3105 /* BRR Format */
3106 case OPCM_32_BRR_EQ_NEQ:
3107 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
3108 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
3109 offset);
3110 } else {
3111 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3112 offset);
3113 }
3114 break;
3115 case OPCM_32_BRR_ADDR_EQ_NEQ:
3116 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
3117 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
3118 offset);
3119 } else {
3120 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
3121 offset);
3122 }
3123 break;
3124 case OPCM_32_BRR_GE:
3125 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
3126 gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3127 offset);
3128 } else {
3129 gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3130 offset);
3131 }
3132 break;
3133 case OPCM_32_BRR_JLT:
3134 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
3135 gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
3136 offset);
3137 } else {
3138 gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3139 offset);
3140 }
3141 break;
3142 case OPCM_32_BRR_LOOP:
3143 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
3144 gen_loop(ctx, r2, offset * 2);
3145 } else {
3146 /* OPC2_32_BRR_LOOPU */
3147 gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3148 }
3149 break;
3150 case OPCM_32_BRR_JNE:
3151 temp = tcg_temp_new_i32();
3152 temp2 = tcg_temp_new_i32();
3153 if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
3154 tcg_gen_mov_i32(temp, cpu_gpr_d[r1]);
3155 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3156 tcg_gen_mov_i32(temp2, cpu_gpr_d[r2]);
3157 /* subi is unconditional */
3158 tcg_gen_subi_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3159 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3160 } else {
3161 tcg_gen_mov_i32(temp, cpu_gpr_d[r1]);
3162 /* also save r2, in case of r1 == r2, so r2 is not decremented */
3163 tcg_gen_mov_i32(temp2, cpu_gpr_d[r2]);
3164 /* addi is unconditional */
3165 tcg_gen_addi_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3166 gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3167 }
3168 break;
3169 case OPCM_32_BRR_JNZ:
3170 if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
3171 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3172 } else {
3173 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3174 }
3175 break;
3176 default:
3177 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3178 }
3179 }
3180
3181
3182 /*
3183 * Functions for decoding instructions
3184 */
3185
3186 static void decode_src_opc(DisasContext *ctx, int op1)
3187 {
3188 int r1;
3189 int32_t const4;
3190 TCGv_i32 temp, temp2;
3191
3192 r1 = MASK_OP_SRC_S1D(ctx->opcode);
3193 const4 = MASK_OP_SRC_CONST4_SEXT(ctx->opcode);
3194
3195 switch (op1) {
3196 case OPC1_16_SRC_ADD:
3197 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3198 break;
3199 case OPC1_16_SRC_ADD_A15:
3200 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[15], const4);
3201 break;
3202 case OPC1_16_SRC_ADD_15A:
3203 gen_addi_d(cpu_gpr_d[15], cpu_gpr_d[r1], const4);
3204 break;
3205 case OPC1_16_SRC_ADD_A:
3206 tcg_gen_addi_i32(cpu_gpr_a[r1], cpu_gpr_a[r1], const4);
3207 break;
3208 case OPC1_16_SRC_CADD:
3209 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3210 cpu_gpr_d[15]);
3211 break;
3212 case OPC1_16_SRC_CADDN:
3213 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3214 cpu_gpr_d[15]);
3215 break;
3216 case OPC1_16_SRC_CMOV:
3217 temp = tcg_constant_i32(0);
3218 temp2 = tcg_constant_i32(const4);
3219 tcg_gen_movcond_i32(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3220 temp2, cpu_gpr_d[r1]);
3221 break;
3222 case OPC1_16_SRC_CMOVN:
3223 temp = tcg_constant_i32(0);
3224 temp2 = tcg_constant_i32(const4);
3225 tcg_gen_movcond_i32(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3226 temp2, cpu_gpr_d[r1]);
3227 break;
3228 case OPC1_16_SRC_EQ:
3229 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3230 const4);
3231 break;
3232 case OPC1_16_SRC_LT:
3233 tcg_gen_setcondi_i32(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3234 const4);
3235 break;
3236 case OPC1_16_SRC_MOV:
3237 tcg_gen_movi_i32(cpu_gpr_d[r1], const4);
3238 break;
3239 case OPC1_16_SRC_MOV_A:
3240 const4 = MASK_OP_SRC_CONST4(ctx->opcode);
3241 tcg_gen_movi_i32(cpu_gpr_a[r1], const4);
3242 break;
3243 case OPC1_16_SRC_MOV_E:
3244 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3245 CHECK_REG_PAIR(r1);
3246 tcg_gen_movi_i32(cpu_gpr_d[r1], const4);
3247 tcg_gen_sari_i32(cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], 31);
3248 } else {
3249 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3250 }
3251 break;
3252 case OPC1_16_SRC_SH:
3253 gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3254 break;
3255 case OPC1_16_SRC_SHA:
3256 gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3257 break;
3258 default:
3259 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3260 }
3261 }
3262
3263 static void decode_srr_opc(DisasContext *ctx, int op1)
3264 {
3265 int r1, r2;
3266 TCGv_i32 temp;
3267
3268 r1 = MASK_OP_SRR_S1D(ctx->opcode);
3269 r2 = MASK_OP_SRR_S2(ctx->opcode);
3270
3271 switch (op1) {
3272 case OPC1_16_SRR_ADD:
3273 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3274 break;
3275 case OPC1_16_SRR_ADD_A15:
3276 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3277 break;
3278 case OPC1_16_SRR_ADD_15A:
3279 gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3280 break;
3281 case OPC1_16_SRR_ADD_A:
3282 tcg_gen_add_i32(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
3283 break;
3284 case OPC1_16_SRR_ADDS:
3285 gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3286 break;
3287 case OPC1_16_SRR_AND:
3288 tcg_gen_and_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3289 break;
3290 case OPC1_16_SRR_CMOV:
3291 temp = tcg_constant_i32(0);
3292 tcg_gen_movcond_i32(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3293 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3294 break;
3295 case OPC1_16_SRR_CMOVN:
3296 temp = tcg_constant_i32(0);
3297 tcg_gen_movcond_i32(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3298 cpu_gpr_d[r2], cpu_gpr_d[r1]);
3299 break;
3300 case OPC1_16_SRR_EQ:
3301 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3302 cpu_gpr_d[r2]);
3303 break;
3304 case OPC1_16_SRR_LT:
3305 tcg_gen_setcond_i32(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3306 cpu_gpr_d[r2]);
3307 break;
3308 case OPC1_16_SRR_MOV:
3309 tcg_gen_mov_i32(cpu_gpr_d[r1], cpu_gpr_d[r2]);
3310 break;
3311 case OPC1_16_SRR_MOV_A:
3312 tcg_gen_mov_i32(cpu_gpr_a[r1], cpu_gpr_d[r2]);
3313 break;
3314 case OPC1_16_SRR_MOV_AA:
3315 tcg_gen_mov_i32(cpu_gpr_a[r1], cpu_gpr_a[r2]);
3316 break;
3317 case OPC1_16_SRR_MOV_D:
3318 tcg_gen_mov_i32(cpu_gpr_d[r1], cpu_gpr_a[r2]);
3319 break;
3320 case OPC1_16_SRR_MUL:
3321 gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3322 break;
3323 case OPC1_16_SRR_OR:
3324 tcg_gen_or_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3325 break;
3326 case OPC1_16_SRR_SUB:
3327 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3328 break;
3329 case OPC1_16_SRR_SUB_A15B:
3330 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3331 break;
3332 case OPC1_16_SRR_SUB_15AB:
3333 gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3334 break;
3335 case OPC1_16_SRR_SUBS:
3336 gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3337 break;
3338 case OPC1_16_SRR_XOR:
3339 tcg_gen_xor_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3340 break;
3341 default:
3342 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3343 }
3344 }
3345
3346 static void decode_ssr_opc(DisasContext *ctx, int op1)
3347 {
3348 int r1, r2;
3349
3350 r1 = MASK_OP_SSR_S1(ctx->opcode);
3351 r2 = MASK_OP_SSR_S2(ctx->opcode);
3352
3353 switch (op1) {
3354 case OPC1_16_SSR_ST_A:
3355 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3356 break;
3357 case OPC1_16_SSR_ST_A_POSTINC:
3358 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3359 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3360 break;
3361 case OPC1_16_SSR_ST_B:
3362 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3363 break;
3364 case OPC1_16_SSR_ST_B_POSTINC:
3365 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3366 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3367 break;
3368 case OPC1_16_SSR_ST_H:
3369 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3370 break;
3371 case OPC1_16_SSR_ST_H_POSTINC:
3372 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3373 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3374 break;
3375 case OPC1_16_SSR_ST_W:
3376 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3377 break;
3378 case OPC1_16_SSR_ST_W_POSTINC:
3379 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3380 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3381 break;
3382 default:
3383 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3384 }
3385 }
3386
3387 static void decode_sc_opc(DisasContext *ctx, int op1)
3388 {
3389 int32_t const16;
3390
3391 const16 = MASK_OP_SC_CONST8(ctx->opcode);
3392
3393 switch (op1) {
3394 case OPC1_16_SC_AND:
3395 tcg_gen_andi_i32(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3396 break;
3397 case OPC1_16_SC_BISR:
3398 if (ctx->priv == TRICORE_PRIV_SM) {
3399 gen_helper_1arg(bisr, const16 & 0xff);
3400 } else {
3401 generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
3402 }
3403 break;
3404 case OPC1_16_SC_LD_A:
3405 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3406 break;
3407 case OPC1_16_SC_LD_W:
3408 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3409 break;
3410 case OPC1_16_SC_MOV:
3411 tcg_gen_movi_i32(cpu_gpr_d[15], const16);
3412 break;
3413 case OPC1_16_SC_OR:
3414 tcg_gen_ori_i32(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3415 break;
3416 case OPC1_16_SC_ST_A:
3417 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3418 break;
3419 case OPC1_16_SC_ST_W:
3420 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3421 break;
3422 case OPC1_16_SC_SUB_A:
3423 tcg_gen_subi_i32(cpu_gpr_a[10], cpu_gpr_a[10], const16);
3424 break;
3425 default:
3426 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3427 }
3428 }
3429
3430 static void decode_slr_opc(DisasContext *ctx, int op1)
3431 {
3432 int r1, r2;
3433
3434 r1 = MASK_OP_SLR_D(ctx->opcode);
3435 r2 = MASK_OP_SLR_S2(ctx->opcode);
3436
3437 switch (op1) {
3438 /* SLR-format */
3439 case OPC1_16_SLR_LD_A:
3440 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3441 break;
3442 case OPC1_16_SLR_LD_A_POSTINC:
3443 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3444 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3445 break;
3446 case OPC1_16_SLR_LD_BU:
3447 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3448 break;
3449 case OPC1_16_SLR_LD_BU_POSTINC:
3450 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3451 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3452 break;
3453 case OPC1_16_SLR_LD_H:
3454 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3455 break;
3456 case OPC1_16_SLR_LD_H_POSTINC:
3457 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3458 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3459 break;
3460 case OPC1_16_SLR_LD_W:
3461 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3462 break;
3463 case OPC1_16_SLR_LD_W_POSTINC:
3464 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3465 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3466 break;
3467 default:
3468 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3469 }
3470 }
3471
3472 static void decode_sro_opc(DisasContext *ctx, int op1)
3473 {
3474 int r2;
3475 int32_t address;
3476
3477 r2 = MASK_OP_SRO_S2(ctx->opcode);
3478 address = MASK_OP_SRO_OFF4(ctx->opcode);
3479
3480 /* SRO-format */
3481 switch (op1) {
3482 case OPC1_16_SRO_LD_A:
3483 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3484 break;
3485 case OPC1_16_SRO_LD_BU:
3486 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3487 break;
3488 case OPC1_16_SRO_LD_H:
3489 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3490 break;
3491 case OPC1_16_SRO_LD_W:
3492 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3493 break;
3494 case OPC1_16_SRO_ST_A:
3495 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3496 break;
3497 case OPC1_16_SRO_ST_B:
3498 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3499 break;
3500 case OPC1_16_SRO_ST_H:
3501 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3502 break;
3503 case OPC1_16_SRO_ST_W:
3504 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3505 break;
3506 default:
3507 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3508 }
3509 }
3510
3511 static void decode_sr_system(DisasContext *ctx)
3512 {
3513 uint32_t op2;
3514 op2 = MASK_OP_SR_OP2(ctx->opcode);
3515
3516 switch (op2) {
3517 case OPC2_16_SR_NOP:
3518 break;
3519 case OPC2_16_SR_RET:
3520 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
3521 break;
3522 case OPC2_16_SR_RFE:
3523 gen_helper_rfe(tcg_env);
3524 ctx->base.is_jmp = DISAS_EXIT;
3525 break;
3526 case OPC2_16_SR_DEBUG:
3527 /* raise EXCP_DEBUG */
3528 break;
3529 case OPC2_16_SR_FRET:
3530 gen_fret(ctx);
3531 break;
3532 default:
3533 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3534 }
3535 }
3536
3537 static void decode_sr_accu(DisasContext *ctx)
3538 {
3539 uint32_t op2;
3540 uint32_t r1;
3541
3542 r1 = MASK_OP_SR_S1D(ctx->opcode);
3543 op2 = MASK_OP_SR_OP2(ctx->opcode);
3544
3545 switch (op2) {
3546 case OPC2_16_SR_RSUB:
3547 /* calc V bit -- overflow only if r1 = -0x80000000 */
3548 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_PSW_V,
3549 cpu_gpr_d[r1], -0x80000000);
3550 tcg_gen_shli_i32(cpu_PSW_V, cpu_PSW_V, 31);
3551 /* calc SV bit */
3552 tcg_gen_or_i32(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
3553 /* sub */
3554 tcg_gen_neg_i32(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3555 /* calc av */
3556 tcg_gen_add_i32(cpu_PSW_AV, cpu_gpr_d[r1], cpu_gpr_d[r1]);
3557 tcg_gen_xor_i32(cpu_PSW_AV, cpu_gpr_d[r1], cpu_PSW_AV);
3558 /* calc sav */
3559 tcg_gen_or_i32(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3560 break;
3561 case OPC2_16_SR_SAT_B:
3562 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
3563 break;
3564 case OPC2_16_SR_SAT_BU:
3565 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
3566 break;
3567 case OPC2_16_SR_SAT_H:
3568 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
3569 break;
3570 case OPC2_16_SR_SAT_HU:
3571 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
3572 break;
3573 default:
3574 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3575 }
3576 }
3577
3578 static void decode_16Bit_opc(DisasContext *ctx)
3579 {
3580 int op1;
3581 int r1, r2;
3582 int32_t const16;
3583 int32_t address;
3584 TCGv_i32 temp;
3585
3586 op1 = MASK_OP_MAJOR(ctx->opcode);
3587
3588 /* handle ADDSC.A opcode only being 6 bit long */
3589 if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
3590 op1 = OPC1_16_SRRS_ADDSC_A;
3591 }
3592
3593 switch (op1) {
3594 case OPC1_16_SRC_ADD:
3595 case OPC1_16_SRC_ADD_A15:
3596 case OPC1_16_SRC_ADD_15A:
3597 case OPC1_16_SRC_ADD_A:
3598 case OPC1_16_SRC_CADD:
3599 case OPC1_16_SRC_CADDN:
3600 case OPC1_16_SRC_CMOV:
3601 case OPC1_16_SRC_CMOVN:
3602 case OPC1_16_SRC_EQ:
3603 case OPC1_16_SRC_LT:
3604 case OPC1_16_SRC_MOV:
3605 case OPC1_16_SRC_MOV_A:
3606 case OPC1_16_SRC_MOV_E:
3607 case OPC1_16_SRC_SH:
3608 case OPC1_16_SRC_SHA:
3609 decode_src_opc(ctx, op1);
3610 break;
3611 /* SRR-format */
3612 case OPC1_16_SRR_ADD:
3613 case OPC1_16_SRR_ADD_A15:
3614 case OPC1_16_SRR_ADD_15A:
3615 case OPC1_16_SRR_ADD_A:
3616 case OPC1_16_SRR_ADDS:
3617 case OPC1_16_SRR_AND:
3618 case OPC1_16_SRR_CMOV:
3619 case OPC1_16_SRR_CMOVN:
3620 case OPC1_16_SRR_EQ:
3621 case OPC1_16_SRR_LT:
3622 case OPC1_16_SRR_MOV:
3623 case OPC1_16_SRR_MOV_A:
3624 case OPC1_16_SRR_MOV_AA:
3625 case OPC1_16_SRR_MOV_D:
3626 case OPC1_16_SRR_MUL:
3627 case OPC1_16_SRR_OR:
3628 case OPC1_16_SRR_SUB:
3629 case OPC1_16_SRR_SUB_A15B:
3630 case OPC1_16_SRR_SUB_15AB:
3631 case OPC1_16_SRR_SUBS:
3632 case OPC1_16_SRR_XOR:
3633 decode_srr_opc(ctx, op1);
3634 break;
3635 /* SSR-format */
3636 case OPC1_16_SSR_ST_A:
3637 case OPC1_16_SSR_ST_A_POSTINC:
3638 case OPC1_16_SSR_ST_B:
3639 case OPC1_16_SSR_ST_B_POSTINC:
3640 case OPC1_16_SSR_ST_H:
3641 case OPC1_16_SSR_ST_H_POSTINC:
3642 case OPC1_16_SSR_ST_W:
3643 case OPC1_16_SSR_ST_W_POSTINC:
3644 decode_ssr_opc(ctx, op1);
3645 break;
3646 /* SRRS-format */
3647 case OPC1_16_SRRS_ADDSC_A:
3648 r2 = MASK_OP_SRRS_S2(ctx->opcode);
3649 r1 = MASK_OP_SRRS_S1D(ctx->opcode);
3650 const16 = MASK_OP_SRRS_N(ctx->opcode);
3651 temp = tcg_temp_new_i32();
3652 tcg_gen_shli_i32(temp, cpu_gpr_d[15], const16);
3653 tcg_gen_add_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
3654 break;
3655 /* SLRO-format */
3656 case OPC1_16_SLRO_LD_A:
3657 r1 = MASK_OP_SLRO_D(ctx->opcode);
3658 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3659 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3660 break;
3661 case OPC1_16_SLRO_LD_BU:
3662 r1 = MASK_OP_SLRO_D(ctx->opcode);
3663 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3664 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
3665 break;
3666 case OPC1_16_SLRO_LD_H:
3667 r1 = MASK_OP_SLRO_D(ctx->opcode);
3668 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3669 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
3670 break;
3671 case OPC1_16_SLRO_LD_W:
3672 r1 = MASK_OP_SLRO_D(ctx->opcode);
3673 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
3674 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3675 break;
3676 /* SB-format */
3677 case OPC1_16_SB_CALL:
3678 case OPC1_16_SB_J:
3679 case OPC1_16_SB_JNZ:
3680 case OPC1_16_SB_JZ:
3681 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
3682 gen_compute_branch(ctx, op1, 0, 0, 0, address);
3683 break;
3684 /* SBC-format */
3685 case OPC1_16_SBC_JEQ:
3686 case OPC1_16_SBC_JNE:
3687 address = MASK_OP_SBC_DISP4(ctx->opcode);
3688 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
3689 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3690 break;
3691 case OPC1_16_SBC_JEQ2:
3692 case OPC1_16_SBC_JNE2:
3693 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3694 address = MASK_OP_SBC_DISP4(ctx->opcode);
3695 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
3696 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3697 } else {
3698 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3699 }
3700 break;
3701 /* SBRN-format */
3702 case OPC1_16_SBRN_JNZ_T:
3703 case OPC1_16_SBRN_JZ_T:
3704 address = MASK_OP_SBRN_DISP4(ctx->opcode);
3705 const16 = MASK_OP_SBRN_N(ctx->opcode);
3706 gen_compute_branch(ctx, op1, 0, 0, const16, address);
3707 break;
3708 /* SBR-format */
3709 case OPC1_16_SBR_JEQ2:
3710 case OPC1_16_SBR_JNE2:
3711 if (has_feature(ctx, TRICORE_FEATURE_16)) {
3712 r1 = MASK_OP_SBR_S2(ctx->opcode);
3713 address = MASK_OP_SBR_DISP4(ctx->opcode);
3714 gen_compute_branch(ctx, op1, r1, 0, 0, address);
3715 } else {
3716 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3717 }
3718 break;
3719 case OPC1_16_SBR_JEQ:
3720 case OPC1_16_SBR_JGEZ:
3721 case OPC1_16_SBR_JGTZ:
3722 case OPC1_16_SBR_JLEZ:
3723 case OPC1_16_SBR_JLTZ:
3724 case OPC1_16_SBR_JNE:
3725 case OPC1_16_SBR_JNZ:
3726 case OPC1_16_SBR_JNZ_A:
3727 case OPC1_16_SBR_JZ:
3728 case OPC1_16_SBR_JZ_A:
3729 case OPC1_16_SBR_LOOP:
3730 r1 = MASK_OP_SBR_S2(ctx->opcode);
3731 address = MASK_OP_SBR_DISP4(ctx->opcode);
3732 gen_compute_branch(ctx, op1, r1, 0, 0, address);
3733 break;
3734 /* SC-format */
3735 case OPC1_16_SC_AND:
3736 case OPC1_16_SC_BISR:
3737 case OPC1_16_SC_LD_A:
3738 case OPC1_16_SC_LD_W:
3739 case OPC1_16_SC_MOV:
3740 case OPC1_16_SC_OR:
3741 case OPC1_16_SC_ST_A:
3742 case OPC1_16_SC_ST_W:
3743 case OPC1_16_SC_SUB_A:
3744 decode_sc_opc(ctx, op1);
3745 break;
3746 /* SLR-format */
3747 case OPC1_16_SLR_LD_A:
3748 case OPC1_16_SLR_LD_A_POSTINC:
3749 case OPC1_16_SLR_LD_BU:
3750 case OPC1_16_SLR_LD_BU_POSTINC:
3751 case OPC1_16_SLR_LD_H:
3752 case OPC1_16_SLR_LD_H_POSTINC:
3753 case OPC1_16_SLR_LD_W:
3754 case OPC1_16_SLR_LD_W_POSTINC:
3755 decode_slr_opc(ctx, op1);
3756 break;
3757 /* SRO-format */
3758 case OPC1_16_SRO_LD_A:
3759 case OPC1_16_SRO_LD_BU:
3760 case OPC1_16_SRO_LD_H:
3761 case OPC1_16_SRO_LD_W:
3762 case OPC1_16_SRO_ST_A:
3763 case OPC1_16_SRO_ST_B:
3764 case OPC1_16_SRO_ST_H:
3765 case OPC1_16_SRO_ST_W:
3766 decode_sro_opc(ctx, op1);
3767 break;
3768 /* SSRO-format */
3769 case OPC1_16_SSRO_ST_A:
3770 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3771 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3772 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3773 break;
3774 case OPC1_16_SSRO_ST_B:
3775 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3776 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3777 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
3778 break;
3779 case OPC1_16_SSRO_ST_H:
3780 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3781 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3782 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
3783 break;
3784 case OPC1_16_SSRO_ST_W:
3785 r1 = MASK_OP_SSRO_S1(ctx->opcode);
3786 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
3787 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
3788 break;
3789 /* SR-format */
3790 case OPCM_16_SR_SYSTEM:
3791 decode_sr_system(ctx);
3792 break;
3793 case OPCM_16_SR_ACCU:
3794 decode_sr_accu(ctx);
3795 break;
3796 case OPC1_16_SR_JI:
3797 r1 = MASK_OP_SR_S1D(ctx->opcode);
3798 gen_compute_branch(ctx, op1, r1, 0, 0, 0);
3799 break;
3800 case OPC1_16_SR_NOT:
3801 r1 = MASK_OP_SR_S1D(ctx->opcode);
3802 tcg_gen_not_i32(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3803 break;
3804 default:
3805 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3806 }
3807 }
3808
3809 /*
3810 * 32 bit instructions
3811 */
3812
3813 /* ABS-format */
3814 static void decode_abs_ldw(DisasContext *ctx)
3815 {
3816 int32_t op2;
3817 int32_t r1;
3818 uint32_t address;
3819 TCGv_i32 temp;
3820
3821 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3822 address = MASK_OP_ABS_OFF18(ctx->opcode);
3823 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3824
3825 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3826
3827 switch (op2) {
3828 case OPC2_32_ABS_LD_A:
3829 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
3830 break;
3831 case OPC2_32_ABS_LD_D:
3832 CHECK_REG_PAIR(r1);
3833 gen_ld_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp);
3834 break;
3835 case OPC2_32_ABS_LD_DA:
3836 CHECK_REG_PAIR(r1);
3837 gen_ld_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp);
3838 break;
3839 case OPC2_32_ABS_LD_W:
3840 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
3841 break;
3842 default:
3843 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3844 }
3845 }
3846
3847 static void decode_abs_ldb(DisasContext *ctx)
3848 {
3849 int32_t op2;
3850 int32_t r1;
3851 uint32_t address;
3852 TCGv_i32 temp;
3853
3854 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3855 address = MASK_OP_ABS_OFF18(ctx->opcode);
3856 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3857
3858 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3859
3860 switch (op2) {
3861 case OPC2_32_ABS_LD_B:
3862 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB);
3863 break;
3864 case OPC2_32_ABS_LD_BU:
3865 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
3866 break;
3867 case OPC2_32_ABS_LD_H:
3868 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW);
3869 break;
3870 case OPC2_32_ABS_LD_HU:
3871 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
3872 break;
3873 default:
3874 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3875 }
3876 }
3877
3878 static void decode_abs_ldst_swap(DisasContext *ctx)
3879 {
3880 int32_t op2;
3881 int32_t r1;
3882 uint32_t address;
3883 TCGv_i32 temp;
3884
3885 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3886 address = MASK_OP_ABS_OFF18(ctx->opcode);
3887 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3888
3889 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3890
3891 switch (op2) {
3892 case OPC2_32_ABS_LDMST:
3893 gen_ldmst(ctx, r1, temp);
3894 break;
3895 case OPC2_32_ABS_SWAP_W:
3896 gen_swap(ctx, r1, temp);
3897 break;
3898 default:
3899 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3900 }
3901 }
3902
3903 static void decode_abs_ldst_context(DisasContext *ctx)
3904 {
3905 uint32_t op2;
3906 int32_t off18;
3907
3908 off18 = MASK_OP_ABS_OFF18(ctx->opcode);
3909 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3910
3911 switch (op2) {
3912 case OPC2_32_ABS_LDLCX:
3913 gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18));
3914 break;
3915 case OPC2_32_ABS_LDUCX:
3916 gen_helper_1arg(lducx, EA_ABS_FORMAT(off18));
3917 break;
3918 case OPC2_32_ABS_STLCX:
3919 gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18));
3920 break;
3921 case OPC2_32_ABS_STUCX:
3922 gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
3923 break;
3924 default:
3925 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3926 }
3927 }
3928
3929 static void decode_abs_store(DisasContext *ctx)
3930 {
3931 int32_t op2;
3932 int32_t r1;
3933 uint32_t address;
3934 TCGv_i32 temp;
3935
3936 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3937 address = MASK_OP_ABS_OFF18(ctx->opcode);
3938 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3939
3940 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3941
3942 switch (op2) {
3943 case OPC2_32_ABS_ST_A:
3944 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
3945 break;
3946 case OPC2_32_ABS_ST_D:
3947 CHECK_REG_PAIR(r1);
3948 gen_st_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp);
3949 break;
3950 case OPC2_32_ABS_ST_DA:
3951 CHECK_REG_PAIR(r1);
3952 gen_st_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp);
3953 break;
3954 case OPC2_32_ABS_ST_W:
3955 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
3956 break;
3957 default:
3958 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3959 }
3960 }
3961
3962 static void decode_abs_storeb_h(DisasContext *ctx)
3963 {
3964 int32_t op2;
3965 int32_t r1;
3966 uint32_t address;
3967 TCGv_i32 temp;
3968
3969 r1 = MASK_OP_ABS_S1D(ctx->opcode);
3970 address = MASK_OP_ABS_OFF18(ctx->opcode);
3971 op2 = MASK_OP_ABS_OP2(ctx->opcode);
3972
3973 temp = tcg_constant_i32(EA_ABS_FORMAT(address));
3974
3975 switch (op2) {
3976 case OPC2_32_ABS_ST_B:
3977 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
3978 break;
3979 case OPC2_32_ABS_ST_H:
3980 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
3981 break;
3982 default:
3983 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3984 }
3985 }
3986
3987 /* Bit-format */
3988
3989 static void decode_bit_andacc(DisasContext *ctx)
3990 {
3991 uint32_t op2;
3992 int r1, r2, r3;
3993 int pos1, pos2;
3994
3995 r1 = MASK_OP_BIT_S1(ctx->opcode);
3996 r2 = MASK_OP_BIT_S2(ctx->opcode);
3997 r3 = MASK_OP_BIT_D(ctx->opcode);
3998 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
3999 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4000 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4001
4002
4003 switch (op2) {
4004 case OPC2_32_BIT_AND_AND_T:
4005 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4006 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
4007 break;
4008 case OPC2_32_BIT_AND_ANDN_T:
4009 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4010 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
4011 break;
4012 case OPC2_32_BIT_AND_NOR_T:
4013 if (tcg_op_supported(INDEX_op_andc, TCG_TYPE_I32, 0)) {
4014 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4015 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
4016 } else {
4017 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4018 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
4019 }
4020 break;
4021 case OPC2_32_BIT_AND_OR_T:
4022 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4023 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
4024 break;
4025 default:
4026 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4027 }
4028 }
4029
4030 static void decode_bit_logical_t(DisasContext *ctx)
4031 {
4032 uint32_t op2;
4033 int r1, r2, r3;
4034 int pos1, pos2;
4035 r1 = MASK_OP_BIT_S1(ctx->opcode);
4036 r2 = MASK_OP_BIT_S2(ctx->opcode);
4037 r3 = MASK_OP_BIT_D(ctx->opcode);
4038 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4039 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4040 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4041
4042 switch (op2) {
4043 case OPC2_32_BIT_AND_T:
4044 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4045 pos1, pos2, &tcg_gen_and_tl);
4046 break;
4047 case OPC2_32_BIT_ANDN_T:
4048 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4049 pos1, pos2, &tcg_gen_andc_tl);
4050 break;
4051 case OPC2_32_BIT_NOR_T:
4052 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4053 pos1, pos2, &tcg_gen_nor_tl);
4054 break;
4055 case OPC2_32_BIT_OR_T:
4056 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4057 pos1, pos2, &tcg_gen_or_tl);
4058 break;
4059 default:
4060 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4061 }
4062 }
4063
4064 static void decode_bit_insert(DisasContext *ctx)
4065 {
4066 uint32_t op2;
4067 int r1, r2, r3;
4068 int pos1, pos2;
4069 TCGv_i32 temp;
4070 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4071 r1 = MASK_OP_BIT_S1(ctx->opcode);
4072 r2 = MASK_OP_BIT_S2(ctx->opcode);
4073 r3 = MASK_OP_BIT_D(ctx->opcode);
4074 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4075 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4076
4077 temp = tcg_temp_new_i32();
4078
4079 tcg_gen_shri_i32(temp, cpu_gpr_d[r2], pos2);
4080 if (op2 == OPC2_32_BIT_INSN_T) {
4081 tcg_gen_not_i32(temp, temp);
4082 }
4083 tcg_gen_deposit_i32(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, pos1, 1);
4084 }
4085
4086 static void decode_bit_logical_t2(DisasContext *ctx)
4087 {
4088 uint32_t op2;
4089
4090 int r1, r2, r3;
4091 int pos1, pos2;
4092
4093 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4094 r1 = MASK_OP_BIT_S1(ctx->opcode);
4095 r2 = MASK_OP_BIT_S2(ctx->opcode);
4096 r3 = MASK_OP_BIT_D(ctx->opcode);
4097 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4098 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4099
4100 switch (op2) {
4101 case OPC2_32_BIT_NAND_T:
4102 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4103 pos1, pos2, &tcg_gen_nand_tl);
4104 break;
4105 case OPC2_32_BIT_ORN_T:
4106 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4107 pos1, pos2, &tcg_gen_orc_tl);
4108 break;
4109 case OPC2_32_BIT_XNOR_T:
4110 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4111 pos1, pos2, &tcg_gen_eqv_tl);
4112 break;
4113 case OPC2_32_BIT_XOR_T:
4114 gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4115 pos1, pos2, &tcg_gen_xor_tl);
4116 break;
4117 default:
4118 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4119 }
4120 }
4121
4122 static void decode_bit_orand(DisasContext *ctx)
4123 {
4124 uint32_t op2;
4125
4126 int r1, r2, r3;
4127 int pos1, pos2;
4128
4129 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4130 r1 = MASK_OP_BIT_S1(ctx->opcode);
4131 r2 = MASK_OP_BIT_S2(ctx->opcode);
4132 r3 = MASK_OP_BIT_D(ctx->opcode);
4133 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4134 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4135
4136 switch (op2) {
4137 case OPC2_32_BIT_OR_AND_T:
4138 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4139 pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl);
4140 break;
4141 case OPC2_32_BIT_OR_ANDN_T:
4142 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4143 pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
4144 break;
4145 case OPC2_32_BIT_OR_NOR_T:
4146 if (tcg_op_supported(INDEX_op_orc, TCG_TYPE_I32, 0)) {
4147 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4148 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
4149 } else {
4150 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4151 pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_or_tl);
4152 }
4153 break;
4154 case OPC2_32_BIT_OR_OR_T:
4155 gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4156 pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
4157 break;
4158 default:
4159 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4160 }
4161 }
4162
4163 static void decode_bit_sh_logic1(DisasContext *ctx)
4164 {
4165 uint32_t op2;
4166 int r1, r2, r3;
4167 int pos1, pos2;
4168 TCGv_i32 temp;
4169
4170 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4171 r1 = MASK_OP_BIT_S1(ctx->opcode);
4172 r2 = MASK_OP_BIT_S2(ctx->opcode);
4173 r3 = MASK_OP_BIT_D(ctx->opcode);
4174 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4175 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4176
4177 temp = tcg_temp_new_i32();
4178
4179 switch (op2) {
4180 case OPC2_32_BIT_SH_AND_T:
4181 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4182 pos1, pos2, &tcg_gen_and_tl);
4183 break;
4184 case OPC2_32_BIT_SH_ANDN_T:
4185 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4186 pos1, pos2, &tcg_gen_andc_tl);
4187 break;
4188 case OPC2_32_BIT_SH_NOR_T:
4189 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4190 pos1, pos2, &tcg_gen_nor_tl);
4191 break;
4192 case OPC2_32_BIT_SH_OR_T:
4193 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4194 pos1, pos2, &tcg_gen_or_tl);
4195 break;
4196 default:
4197 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4198 }
4199 tcg_gen_shli_i32(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4200 tcg_gen_add_i32(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4201 }
4202
4203 static void decode_bit_sh_logic2(DisasContext *ctx)
4204 {
4205 uint32_t op2;
4206 int r1, r2, r3;
4207 int pos1, pos2;
4208 TCGv_i32 temp;
4209
4210 op2 = MASK_OP_BIT_OP2(ctx->opcode);
4211 r1 = MASK_OP_BIT_S1(ctx->opcode);
4212 r2 = MASK_OP_BIT_S2(ctx->opcode);
4213 r3 = MASK_OP_BIT_D(ctx->opcode);
4214 pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4215 pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4216
4217 temp = tcg_temp_new_i32();
4218
4219 switch (op2) {
4220 case OPC2_32_BIT_SH_NAND_T:
4221 gen_bit_1op(temp, cpu_gpr_d[r1] , cpu_gpr_d[r2] ,
4222 pos1, pos2, &tcg_gen_nand_tl);
4223 break;
4224 case OPC2_32_BIT_SH_ORN_T:
4225 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4226 pos1, pos2, &tcg_gen_orc_tl);
4227 break;
4228 case OPC2_32_BIT_SH_XNOR_T:
4229 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4230 pos1, pos2, &tcg_gen_eqv_tl);
4231 break;
4232 case OPC2_32_BIT_SH_XOR_T:
4233 gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4234 pos1, pos2, &tcg_gen_xor_tl);
4235 break;
4236 default:
4237 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4238 }
4239 tcg_gen_shli_i32(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4240 tcg_gen_add_i32(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4241 }
4242
4243 /* BO-format */
4244
4245
4246 static void decode_bo_addrmode_post_pre_base(DisasContext *ctx)
4247 {
4248 uint32_t op2;
4249 uint32_t off10;
4250 int32_t r1, r2;
4251 TCGv_i32 temp;
4252
4253 r1 = MASK_OP_BO_S1D(ctx->opcode);
4254 r2 = MASK_OP_BO_S2(ctx->opcode);
4255 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4256 op2 = MASK_OP_BO_OP2(ctx->opcode);
4257
4258 switch (op2) {
4259 case OPC2_32_BO_CACHEA_WI_SHORTOFF:
4260 case OPC2_32_BO_CACHEA_W_SHORTOFF:
4261 case OPC2_32_BO_CACHEA_I_SHORTOFF:
4262 /* instruction to access the cache */
4263 break;
4264 case OPC2_32_BO_CACHEA_WI_POSTINC:
4265 case OPC2_32_BO_CACHEA_W_POSTINC:
4266 case OPC2_32_BO_CACHEA_I_POSTINC:
4267 /* instruction to access the cache, but we still need to handle
4268 the addressing mode */
4269 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4270 break;
4271 case OPC2_32_BO_CACHEA_WI_PREINC:
4272 case OPC2_32_BO_CACHEA_W_PREINC:
4273 case OPC2_32_BO_CACHEA_I_PREINC:
4274 /* instruction to access the cache, but we still need to handle
4275 the addressing mode */
4276 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4277 break;
4278 case OPC2_32_BO_CACHEI_WI_SHORTOFF:
4279 case OPC2_32_BO_CACHEI_W_SHORTOFF:
4280 if (!has_feature(ctx, TRICORE_FEATURE_131)) {
4281 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4282 }
4283 break;
4284 case OPC2_32_BO_CACHEI_W_POSTINC:
4285 case OPC2_32_BO_CACHEI_WI_POSTINC:
4286 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4287 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4288 } else {
4289 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4290 }
4291 break;
4292 case OPC2_32_BO_CACHEI_W_PREINC:
4293 case OPC2_32_BO_CACHEI_WI_PREINC:
4294 if (has_feature(ctx, TRICORE_FEATURE_131)) {
4295 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4296 } else {
4297 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4298 }
4299 break;
4300 case OPC2_32_BO_ST_A_SHORTOFF:
4301 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4302 break;
4303 case OPC2_32_BO_ST_A_POSTINC:
4304 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4305 MO_LESL);
4306 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4307 break;
4308 case OPC2_32_BO_ST_A_PREINC:
4309 gen_st_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4310 break;
4311 case OPC2_32_BO_ST_B_SHORTOFF:
4312 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4313 break;
4314 case OPC2_32_BO_ST_B_POSTINC:
4315 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4316 MO_UB);
4317 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4318 break;
4319 case OPC2_32_BO_ST_B_PREINC:
4320 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4321 break;
4322 case OPC2_32_BO_ST_D_SHORTOFF:
4323 CHECK_REG_PAIR(r1);
4324 gen_offset_st_2regs(ctx,
4325 cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4326 off10);
4327 break;
4328 case OPC2_32_BO_ST_D_POSTINC:
4329 CHECK_REG_PAIR(r1);
4330 gen_st_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], cpu_gpr_a[r2]);
4331 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4332 break;
4333 case OPC2_32_BO_ST_D_PREINC:
4334 CHECK_REG_PAIR(r1);
4335 temp = tcg_temp_new_i32();
4336 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4337 gen_st_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp);
4338 tcg_gen_mov_i32(cpu_gpr_a[r2], temp);
4339 break;
4340 case OPC2_32_BO_ST_DA_SHORTOFF:
4341 CHECK_REG_PAIR(r1);
4342 gen_offset_st_2regs(ctx,
4343 cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4344 off10);
4345 break;
4346 case OPC2_32_BO_ST_DA_POSTINC:
4347 CHECK_REG_PAIR(r1);
4348 gen_st_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
4349 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4350 break;
4351 case OPC2_32_BO_ST_DA_PREINC:
4352 CHECK_REG_PAIR(r1);
4353 temp = tcg_temp_new_i32();
4354 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4355 gen_st_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp);
4356 tcg_gen_mov_i32(cpu_gpr_a[r2], temp);
4357 break;
4358 case OPC2_32_BO_ST_H_SHORTOFF:
4359 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4360 break;
4361 case OPC2_32_BO_ST_H_POSTINC:
4362 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4363 MO_LEUW);
4364 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4365 break;
4366 case OPC2_32_BO_ST_H_PREINC:
4367 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4368 break;
4369 case OPC2_32_BO_ST_Q_SHORTOFF:
4370 temp = tcg_temp_new_i32();
4371 tcg_gen_shri_i32(temp, cpu_gpr_d[r1], 16);
4372 gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4373 break;
4374 case OPC2_32_BO_ST_Q_POSTINC:
4375 temp = tcg_temp_new_i32();
4376 tcg_gen_shri_i32(temp, cpu_gpr_d[r1], 16);
4377 tcg_gen_qemu_st_i32(temp, cpu_gpr_a[r2], ctx->mem_idx,
4378 MO_LEUW);
4379 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4380 break;
4381 case OPC2_32_BO_ST_Q_PREINC:
4382 temp = tcg_temp_new_i32();
4383 tcg_gen_shri_i32(temp, cpu_gpr_d[r1], 16);
4384 gen_st_preincr(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4385 break;
4386 case OPC2_32_BO_ST_W_SHORTOFF:
4387 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4388 break;
4389 case OPC2_32_BO_ST_W_POSTINC:
4390 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4391 MO_LEUL);
4392 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4393 break;
4394 case OPC2_32_BO_ST_W_PREINC:
4395 gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4396 break;
4397 default:
4398 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4399 }
4400 }
4401
4402 static void decode_bo_addrmode_bitreverse_circular(DisasContext *ctx)
4403 {
4404 uint32_t op2;
4405 uint32_t off10;
4406 int32_t r1, r2;
4407 TCGv_i32 temp, temp2, t_off10;
4408
4409 r1 = MASK_OP_BO_S1D(ctx->opcode);
4410 r2 = MASK_OP_BO_S2(ctx->opcode);
4411 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4412 op2 = MASK_OP_BO_OP2(ctx->opcode);
4413
4414 temp = tcg_temp_new_i32();
4415 temp2 = tcg_temp_new_i32();
4416 t_off10 = tcg_constant_i32(off10);
4417 CHECK_REG_PAIR(r2);
4418 tcg_gen_ext16u_i32(temp, cpu_gpr_a[r2 + 1]);
4419 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4420
4421 switch (op2) {
4422 case OPC2_32_BO_CACHEA_WI_BR:
4423 case OPC2_32_BO_CACHEA_W_BR:
4424 case OPC2_32_BO_CACHEA_I_BR:
4425 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4426 break;
4427 case OPC2_32_BO_CACHEA_WI_CIRC:
4428 case OPC2_32_BO_CACHEA_W_CIRC:
4429 case OPC2_32_BO_CACHEA_I_CIRC:
4430 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4431 break;
4432 case OPC2_32_BO_ST_A_BR:
4433 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4434 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4435 break;
4436 case OPC2_32_BO_ST_A_CIRC:
4437 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4438 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4439 break;
4440 case OPC2_32_BO_ST_B_BR:
4441 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4442 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4443 break;
4444 case OPC2_32_BO_ST_B_CIRC:
4445 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4446 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4447 break;
4448 case OPC2_32_BO_ST_D_BR:
4449 CHECK_REG_PAIR(r1);
4450 gen_st_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp2);
4451 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4452 break;
4453 case OPC2_32_BO_ST_D_CIRC:
4454 CHECK_REG_PAIR(r1);
4455 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4456 tcg_gen_shri_i32(temp2, cpu_gpr_a[r2 + 1], 16);
4457 tcg_gen_addi_i32(temp, temp, 4);
4458 tcg_gen_rem_i32(temp, temp, temp2);
4459 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4460 tcg_gen_qemu_st_i32(cpu_gpr_d[r1 + 1], temp2, ctx->mem_idx, MO_LEUL);
4461 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4462 break;
4463 case OPC2_32_BO_ST_DA_BR:
4464 CHECK_REG_PAIR(r1);
4465 gen_st_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp2);
4466 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4467 break;
4468 case OPC2_32_BO_ST_DA_CIRC:
4469 CHECK_REG_PAIR(r1);
4470 tcg_gen_qemu_st_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4471 tcg_gen_shri_i32(temp2, cpu_gpr_a[r2 + 1], 16);
4472 tcg_gen_addi_i32(temp, temp, 4);
4473 tcg_gen_rem_i32(temp, temp, temp2);
4474 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4475 tcg_gen_qemu_st_i32(cpu_gpr_a[r1 + 1], temp2, ctx->mem_idx, MO_LEUL);
4476 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4477 break;
4478 case OPC2_32_BO_ST_H_BR:
4479 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4480 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4481 break;
4482 case OPC2_32_BO_ST_H_CIRC:
4483 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4484 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4485 break;
4486 case OPC2_32_BO_ST_Q_BR:
4487 tcg_gen_shri_i32(temp, cpu_gpr_d[r1], 16);
4488 tcg_gen_qemu_st_i32(temp, temp2, ctx->mem_idx, MO_LEUW);
4489 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4490 break;
4491 case OPC2_32_BO_ST_Q_CIRC:
4492 tcg_gen_shri_i32(temp, cpu_gpr_d[r1], 16);
4493 tcg_gen_qemu_st_i32(temp, temp2, ctx->mem_idx, MO_LEUW);
4494 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4495 break;
4496 case OPC2_32_BO_ST_W_BR:
4497 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4498 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4499 break;
4500 case OPC2_32_BO_ST_W_CIRC:
4501 tcg_gen_qemu_st_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4502 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4503 break;
4504 default:
4505 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4506 }
4507 }
4508
4509 static void decode_bo_addrmode_ld_post_pre_base(DisasContext *ctx)
4510 {
4511 uint32_t op2;
4512 uint32_t off10;
4513 int32_t r1, r2;
4514 TCGv_i32 temp;
4515
4516 r1 = MASK_OP_BO_S1D(ctx->opcode);
4517 r2 = MASK_OP_BO_S2(ctx->opcode);
4518 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4519 op2 = MASK_OP_BO_OP2(ctx->opcode);
4520
4521 switch (op2) {
4522 case OPC2_32_BO_LD_A_SHORTOFF:
4523 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4524 break;
4525 case OPC2_32_BO_LD_A_POSTINC:
4526 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4527 MO_LEUL);
4528 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4529 break;
4530 case OPC2_32_BO_LD_A_PREINC:
4531 gen_ld_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4532 break;
4533 case OPC2_32_BO_LD_B_SHORTOFF:
4534 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4535 break;
4536 case OPC2_32_BO_LD_B_POSTINC:
4537 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4538 MO_SB);
4539 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4540 break;
4541 case OPC2_32_BO_LD_B_PREINC:
4542 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
4543 break;
4544 case OPC2_32_BO_LD_BU_SHORTOFF:
4545 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4546 break;
4547 case OPC2_32_BO_LD_BU_POSTINC:
4548 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4549 MO_UB);
4550 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4551 break;
4552 case OPC2_32_BO_LD_BU_PREINC:
4553 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4554 break;
4555 case OPC2_32_BO_LD_D_SHORTOFF:
4556 CHECK_REG_PAIR(r1);
4557 gen_offset_ld_2regs(ctx,
4558 cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4559 off10);
4560 break;
4561 case OPC2_32_BO_LD_D_POSTINC:
4562 CHECK_REG_PAIR(r1);
4563 gen_ld_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], cpu_gpr_a[r2]);
4564 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4565 break;
4566 case OPC2_32_BO_LD_D_PREINC:
4567 CHECK_REG_PAIR(r1);
4568 temp = tcg_temp_new_i32();
4569 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4570 gen_ld_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp);
4571 tcg_gen_mov_i32(cpu_gpr_a[r2], temp);
4572 break;
4573 case OPC2_32_BO_LD_DA_SHORTOFF:
4574 CHECK_REG_PAIR(r1);
4575 gen_offset_ld_2regs(ctx,
4576 cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4577 off10);
4578 break;
4579 case OPC2_32_BO_LD_DA_POSTINC:
4580 CHECK_REG_PAIR(r1);
4581 gen_ld_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
4582 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4583 break;
4584 case OPC2_32_BO_LD_DA_PREINC:
4585 CHECK_REG_PAIR(r1);
4586 temp = tcg_temp_new_i32();
4587 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4588 gen_ld_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp);
4589 tcg_gen_mov_i32(cpu_gpr_a[r2], temp);
4590 break;
4591 case OPC2_32_BO_LD_H_SHORTOFF:
4592 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
4593 break;
4594 case OPC2_32_BO_LD_H_POSTINC:
4595 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4596 MO_LESW);
4597 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4598 break;
4599 case OPC2_32_BO_LD_H_PREINC:
4600 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW);
4601 break;
4602 case OPC2_32_BO_LD_HU_SHORTOFF:
4603 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4604 break;
4605 case OPC2_32_BO_LD_HU_POSTINC:
4606 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4607 MO_LEUW);
4608 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4609 break;
4610 case OPC2_32_BO_LD_HU_PREINC:
4611 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4612 break;
4613 case OPC2_32_BO_LD_Q_SHORTOFF:
4614 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4615 tcg_gen_shli_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4616 break;
4617 case OPC2_32_BO_LD_Q_POSTINC:
4618 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4619 MO_LEUW);
4620 tcg_gen_shli_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4621 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4622 break;
4623 case OPC2_32_BO_LD_Q_PREINC:
4624 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4625 tcg_gen_shli_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4626 break;
4627 case OPC2_32_BO_LD_W_SHORTOFF:
4628 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4629 break;
4630 case OPC2_32_BO_LD_W_POSTINC:
4631 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4632 MO_LEUL);
4633 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4634 break;
4635 case OPC2_32_BO_LD_W_PREINC:
4636 gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
4637 break;
4638 default:
4639 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4640 }
4641 }
4642
4643 static void decode_bo_addrmode_ld_bitreverse_circular(DisasContext *ctx)
4644 {
4645 uint32_t op2;
4646 uint32_t off10;
4647 int r1, r2;
4648 TCGv_i32 temp, temp2, t_off10;
4649
4650 r1 = MASK_OP_BO_S1D(ctx->opcode);
4651 r2 = MASK_OP_BO_S2(ctx->opcode);
4652 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4653 op2 = MASK_OP_BO_OP2(ctx->opcode);
4654
4655 temp = tcg_temp_new_i32();
4656 temp2 = tcg_temp_new_i32();
4657 t_off10 = tcg_constant_i32(off10);
4658 CHECK_REG_PAIR(r2);
4659 tcg_gen_ext16u_i32(temp, cpu_gpr_a[r2 + 1]);
4660 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4661
4662
4663 switch (op2) {
4664 case OPC2_32_BO_LD_A_BR:
4665 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4666 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4667 break;
4668 case OPC2_32_BO_LD_A_CIRC:
4669 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4670 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4671 break;
4672 case OPC2_32_BO_LD_B_BR:
4673 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
4674 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4675 break;
4676 case OPC2_32_BO_LD_B_CIRC:
4677 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB);
4678 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4679 break;
4680 case OPC2_32_BO_LD_BU_BR:
4681 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4682 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4683 break;
4684 case OPC2_32_BO_LD_BU_CIRC:
4685 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB);
4686 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4687 break;
4688 case OPC2_32_BO_LD_D_BR:
4689 CHECK_REG_PAIR(r1);
4690 gen_ld_2regs_64(ctx, cpu_gpr_d[r1 + 1], cpu_gpr_d[r1], temp2);
4691 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4692 break;
4693 case OPC2_32_BO_LD_D_CIRC:
4694 CHECK_REG_PAIR(r1);
4695 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4696 tcg_gen_shri_i32(temp2, cpu_gpr_a[r2 + 1], 16);
4697 tcg_gen_addi_i32(temp, temp, 4);
4698 tcg_gen_rem_i32(temp, temp, temp2);
4699 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4700 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1 + 1], temp2, ctx->mem_idx, MO_LEUL);
4701 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4702 break;
4703 case OPC2_32_BO_LD_DA_BR:
4704 CHECK_REG_PAIR(r1);
4705 gen_ld_2regs_64(ctx, cpu_gpr_a[r1 + 1], cpu_gpr_a[r1], temp2);
4706 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4707 break;
4708 case OPC2_32_BO_LD_DA_CIRC:
4709 CHECK_REG_PAIR(r1);
4710 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
4711 tcg_gen_shri_i32(temp2, cpu_gpr_a[r2 + 1], 16);
4712 tcg_gen_addi_i32(temp, temp, 4);
4713 tcg_gen_rem_i32(temp, temp, temp2);
4714 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4715 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1 + 1], 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 case OPC2_32_BO_LD_H_BR:
4719 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
4720 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4721 break;
4722 case OPC2_32_BO_LD_H_CIRC:
4723 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW);
4724 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4725 break;
4726 case OPC2_32_BO_LD_HU_BR:
4727 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4728 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4729 break;
4730 case OPC2_32_BO_LD_HU_CIRC:
4731 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4732 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4733 break;
4734 case OPC2_32_BO_LD_Q_BR:
4735 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4736 tcg_gen_shli_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4737 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4738 break;
4739 case OPC2_32_BO_LD_Q_CIRC:
4740 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW);
4741 tcg_gen_shli_i32(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
4742 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4743 break;
4744 case OPC2_32_BO_LD_W_BR:
4745 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4746 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4747 break;
4748 case OPC2_32_BO_LD_W_CIRC:
4749 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
4750 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4751 break;
4752 default:
4753 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4754 }
4755 }
4756
4757 static void decode_bo_addrmode_stctx_post_pre_base(DisasContext *ctx)
4758 {
4759 uint32_t op2;
4760 uint32_t off10;
4761 int r1, r2;
4762
4763 TCGv_i32 temp;
4764
4765 r1 = MASK_OP_BO_S1D(ctx->opcode);
4766 r2 = MASK_OP_BO_S2(ctx->opcode);
4767 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4768 op2 = MASK_OP_BO_OP2(ctx->opcode);
4769
4770
4771 temp = tcg_temp_new_i32();
4772
4773 switch (op2) {
4774 case OPC2_32_BO_LDLCX_SHORTOFF:
4775 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4776 gen_helper_ldlcx(tcg_env, temp);
4777 break;
4778 case OPC2_32_BO_LDMST_SHORTOFF:
4779 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4780 gen_ldmst(ctx, r1, temp);
4781 break;
4782 case OPC2_32_BO_LDMST_POSTINC:
4783 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
4784 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4785 break;
4786 case OPC2_32_BO_LDMST_PREINC:
4787 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4788 gen_ldmst(ctx, r1, cpu_gpr_a[r2]);
4789 break;
4790 case OPC2_32_BO_LDUCX_SHORTOFF:
4791 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4792 gen_helper_lducx(tcg_env, temp);
4793 break;
4794 case OPC2_32_BO_LEA_SHORTOFF:
4795 tcg_gen_addi_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], off10);
4796 break;
4797 case OPC2_32_BO_STLCX_SHORTOFF:
4798 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4799 gen_helper_stlcx(tcg_env, temp);
4800 break;
4801 case OPC2_32_BO_STUCX_SHORTOFF:
4802 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4803 gen_helper_stucx(tcg_env, temp);
4804 break;
4805 case OPC2_32_BO_SWAP_W_SHORTOFF:
4806 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4807 gen_swap(ctx, r1, temp);
4808 break;
4809 case OPC2_32_BO_SWAP_W_POSTINC:
4810 gen_swap(ctx, r1, cpu_gpr_a[r2]);
4811 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4812 break;
4813 case OPC2_32_BO_SWAP_W_PREINC:
4814 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4815 gen_swap(ctx, r1, cpu_gpr_a[r2]);
4816 break;
4817 case OPC2_32_BO_CMPSWAP_W_SHORTOFF:
4818 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4819 gen_cmpswap(ctx, r1, temp);
4820 break;
4821 case OPC2_32_BO_CMPSWAP_W_POSTINC:
4822 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
4823 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4824 break;
4825 case OPC2_32_BO_CMPSWAP_W_PREINC:
4826 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4827 gen_cmpswap(ctx, r1, cpu_gpr_a[r2]);
4828 break;
4829 case OPC2_32_BO_SWAPMSK_W_SHORTOFF:
4830 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], off10);
4831 gen_swapmsk(ctx, r1, temp);
4832 break;
4833 case OPC2_32_BO_SWAPMSK_W_POSTINC:
4834 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
4835 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4836 break;
4837 case OPC2_32_BO_SWAPMSK_W_PREINC:
4838 tcg_gen_addi_i32(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4839 gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
4840 break;
4841 default:
4842 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4843 }
4844 }
4845
4846 static void decode_bo_addrmode_ldmst_bitreverse_circular(DisasContext *ctx)
4847 {
4848 uint32_t op2;
4849 uint32_t off10;
4850 int r1, r2;
4851 TCGv_i32 temp, temp2, t_off10;
4852
4853 r1 = MASK_OP_BO_S1D(ctx->opcode);
4854 r2 = MASK_OP_BO_S2(ctx->opcode);
4855 off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4856 op2 = MASK_OP_BO_OP2(ctx->opcode);
4857
4858 temp = tcg_temp_new_i32();
4859 temp2 = tcg_temp_new_i32();
4860 t_off10 = tcg_constant_i32(off10);
4861 CHECK_REG_PAIR(r2);
4862 tcg_gen_ext16u_i32(temp, cpu_gpr_a[r2 + 1]);
4863 tcg_gen_add_i32(temp2, cpu_gpr_a[r2], temp);
4864
4865 switch (op2) {
4866 case OPC2_32_BO_LDMST_BR:
4867 gen_ldmst(ctx, r1, temp2);
4868 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4869 break;
4870 case OPC2_32_BO_LDMST_CIRC:
4871 gen_ldmst(ctx, r1, temp2);
4872 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4873 break;
4874 case OPC2_32_BO_SWAP_W_BR:
4875 gen_swap(ctx, r1, temp2);
4876 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4877 break;
4878 case OPC2_32_BO_SWAP_W_CIRC:
4879 gen_swap(ctx, r1, temp2);
4880 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4881 break;
4882 case OPC2_32_BO_CMPSWAP_W_BR:
4883 gen_cmpswap(ctx, r1, temp2);
4884 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4885 break;
4886 case OPC2_32_BO_CMPSWAP_W_CIRC:
4887 gen_cmpswap(ctx, r1, temp2);
4888 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4889 break;
4890 case OPC2_32_BO_SWAPMSK_W_BR:
4891 gen_swapmsk(ctx, r1, temp2);
4892 gen_helper_br_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1]);
4893 break;
4894 case OPC2_32_BO_SWAPMSK_W_CIRC:
4895 gen_swapmsk(ctx, r1, temp2);
4896 gen_helper_circ_update(cpu_gpr_a[r2 + 1], cpu_gpr_a[r2 + 1], t_off10);
4897 break;
4898 default:
4899 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4900 }
4901 }
4902
4903 static void decode_bol_opc(DisasContext *ctx, int32_t op1)
4904 {
4905 int r1, r2;
4906 int32_t address;
4907 TCGv_i32 temp;
4908
4909 r1 = MASK_OP_BOL_S1D(ctx->opcode);
4910 r2 = MASK_OP_BOL_S2(ctx->opcode);
4911 address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);
4912
4913 switch (op1) {
4914 case OPC1_32_BOL_LD_A_LONGOFF:
4915 temp = tcg_temp_new_i32();
4916 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], address);
4917 tcg_gen_qemu_ld_i32(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
4918 break;
4919 case OPC1_32_BOL_LD_W_LONGOFF:
4920 temp = tcg_temp_new_i32();
4921 tcg_gen_addi_i32(temp, cpu_gpr_a[r2], address);
4922 tcg_gen_qemu_ld_i32(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
4923 break;
4924 case OPC1_32_BOL_LEA_LONGOFF:
4925 tcg_gen_addi_i32(cpu_gpr_a[r1], cpu_gpr_a[r2], address);
4926 break;
4927 case OPC1_32_BOL_ST_A_LONGOFF:
4928 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4929 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
4930 } else {
4931 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4932 }
4933 break;
4934 case OPC1_32_BOL_ST_W_LONGOFF:
4935 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
4936 break;
4937 case OPC1_32_BOL_LD_B_LONGOFF:
4938 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4939 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
4940 } else {
4941 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4942 }
4943 break;
4944 case OPC1_32_BOL_LD_BU_LONGOFF:
4945 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4946 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);
4947 } else {
4948 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4949 }
4950 break;
4951 case OPC1_32_BOL_LD_H_LONGOFF:
4952 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4953 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
4954 } else {
4955 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4956 }
4957 break;
4958 case OPC1_32_BOL_LD_HU_LONGOFF:
4959 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4960 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);
4961 } else {
4962 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4963 }
4964 break;
4965 case OPC1_32_BOL_ST_B_LONGOFF:
4966 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4967 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
4968 } else {
4969 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4970 }
4971 break;
4972 case OPC1_32_BOL_ST_H_LONGOFF:
4973 if (has_feature(ctx, TRICORE_FEATURE_16)) {
4974 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
4975 } else {
4976 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4977 }
4978 break;
4979 default:
4980 generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4981 }
4982 }
4983
4984 /* RC format */
4985 static void decode_rc_logical_shift(DisasContext *ctx)
4986 {
4987 uint32_t op2;
4988 int r1, r2;
4989 int32_t const9;
4990 TCGv_i32 temp;
4991
4992 r2 = MASK_OP_RC_D(ctx->opcode);
4993 r1 = MASK_OP_RC_S1(ctx->opcode);
4994 const9 = MASK_OP_RC_CONST9(ctx->opcode);
4995 op2 = MASK_OP_RC_OP2(ctx->opcode);
4996
4997 switch (op2) {
4998 case OPC2_32_RC_AND:
4999 tcg_gen_andi_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
5000 break;
Showing first 5,000 of 8,566 lines. View raw