target-tricore: Add instructions of ABS, ABSB opcode format
[qemu/ar7.git] / target-tricore / translate.c
blobfc89a4357ac36eca277123682029d227f1e4e670
1 /*
2 * TriCore emulation for qemu: main translation routines.
4 * Copyright (c) 2013-2014 Bastian Koppelmann C-Lab/University Paderborn
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 of the License, or (at your option) any later version.
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.
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/>.
21 #include "cpu.h"
22 #include "disas/disas.h"
23 #include "tcg-op.h"
24 #include "exec/cpu_ldst.h"
26 #include "exec/helper-proto.h"
27 #include "exec/helper-gen.h"
29 #include "tricore-opcodes.h"
32 * TCG registers
34 static TCGv cpu_PC;
35 static TCGv cpu_PCXI;
36 static TCGv cpu_PSW;
37 static TCGv cpu_ICR;
38 /* GPR registers */
39 static TCGv cpu_gpr_a[16];
40 static TCGv cpu_gpr_d[16];
41 /* PSW Flag cache */
42 static TCGv cpu_PSW_C;
43 static TCGv cpu_PSW_V;
44 static TCGv cpu_PSW_SV;
45 static TCGv cpu_PSW_AV;
46 static TCGv cpu_PSW_SAV;
47 /* CPU env */
48 static TCGv_ptr cpu_env;
50 #include "exec/gen-icount.h"
52 static const char *regnames_a[] = {
53 "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
54 "a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
55 "a12" , "a13" , "a14" , "a15",
58 static const char *regnames_d[] = {
59 "d0" , "d1" , "d2" , "d3" , "d4" , "d5" ,
60 "d6" , "d7" , "d8" , "d9" , "d10" , "d11" ,
61 "d12" , "d13" , "d14" , "d15",
64 typedef struct DisasContext {
65 struct TranslationBlock *tb;
66 target_ulong pc, saved_pc, next_pc;
67 uint32_t opcode;
68 int singlestep_enabled;
69 /* Routine used to access memory */
70 int mem_idx;
71 uint32_t hflags, saved_hflags;
72 int bstate;
73 } DisasContext;
75 enum {
77 BS_NONE = 0,
78 BS_STOP = 1,
79 BS_BRANCH = 2,
80 BS_EXCP = 3,
83 void tricore_cpu_dump_state(CPUState *cs, FILE *f,
84 fprintf_function cpu_fprintf, int flags)
86 TriCoreCPU *cpu = TRICORE_CPU(cs);
87 CPUTriCoreState *env = &cpu->env;
88 int i;
90 cpu_fprintf(f, "PC=%08x\n", env->PC);
91 for (i = 0; i < 16; ++i) {
92 if ((i & 3) == 0) {
93 cpu_fprintf(f, "GPR A%02d:", i);
95 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames_a[i], env->gpr_a[i]);
97 for (i = 0; i < 16; ++i) {
98 if ((i & 3) == 0) {
99 cpu_fprintf(f, "GPR D%02d:", i);
101 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames_d[i], env->gpr_d[i]);
107 * Functions to generate micro-ops
110 /* Makros for generating helpers */
112 #define gen_helper_1arg(name, arg) do { \
113 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
114 gen_helper_##name(cpu_env, helper_tmp); \
115 tcg_temp_free_i32(helper_tmp); \
116 } while (0)
118 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
120 /* Functions for load/save to/from memory */
122 static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
123 int16_t con, TCGMemOp mop)
125 TCGv temp = tcg_temp_new();
126 tcg_gen_addi_tl(temp, r2, con);
127 tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
128 tcg_temp_free(temp);
131 static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
132 int16_t con, TCGMemOp mop)
134 TCGv temp = tcg_temp_new();
135 tcg_gen_addi_tl(temp, r2, con);
136 tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
137 tcg_temp_free(temp);
140 static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
142 TCGv_i64 temp = tcg_temp_new_i64();
144 tcg_gen_concat_i32_i64(temp, rl, rh);
145 tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
147 tcg_temp_free_i64(temp);
150 static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
152 TCGv_i64 temp = tcg_temp_new_i64();
154 tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
155 /* write back to two 32 bit regs */
156 tcg_gen_extr_i64_i32(rl, rh, temp);
158 tcg_temp_free_i64(temp);
161 /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
162 static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
164 TCGv temp = tcg_temp_new();
165 TCGv temp2 = tcg_temp_new();
167 /* temp = (M(EA, word) */
168 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
169 /* temp = temp & ~E[a][63:32]) */
170 tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
171 /* temp2 = (E[a][31:0] & E[a][63:32]); */
172 tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
173 /* temp = temp | temp2; */
174 tcg_gen_or_tl(temp, temp, temp2);
175 /* M(EA, word) = temp; */
176 tcg_gen_qemu_st_tl(temp, ea, ctx->mem_idx, MO_LEUL);
178 tcg_temp_free(temp);
179 tcg_temp_free(temp2);
182 /* tmp = M(EA, word);
183 M(EA, word) = D[a];
184 D[a] = tmp[31:0];*/
185 static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
187 TCGv temp = tcg_temp_new();
189 tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
190 tcg_gen_qemu_st_tl(cpu_gpr_d[reg], ea, ctx->mem_idx, MO_LEUL);
191 tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
193 tcg_temp_free(temp);
196 /* Functions for arithmetic instructions */
198 static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
200 TCGv t0 = tcg_temp_new_i32();
201 TCGv result = tcg_temp_new_i32();
202 /* Addition and set V/SV bits */
203 tcg_gen_add_tl(result, r1, r2);
204 /* calc V bit */
205 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
206 tcg_gen_xor_tl(t0, r1, r2);
207 tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
208 /* Calc SV bit */
209 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
210 /* Calc AV/SAV bits */
211 tcg_gen_add_tl(cpu_PSW_AV, result, result);
212 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
213 /* calc SAV */
214 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
215 /* write back result */
216 tcg_gen_mov_tl(ret, result);
218 tcg_temp_free(result);
219 tcg_temp_free(t0);
222 static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
224 TCGv temp = tcg_const_i32(r2);
225 gen_add_d(ret, r1, temp);
226 tcg_temp_free(temp);
229 static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
230 TCGv r4)
232 TCGv temp = tcg_temp_new();
233 TCGv temp2 = tcg_temp_new();
234 TCGv result = tcg_temp_new();
235 TCGv mask = tcg_temp_new();
236 TCGv t0 = tcg_const_i32(0);
238 /* create mask for sticky bits */
239 tcg_gen_setcond_tl(cond, mask, r4, t0);
240 tcg_gen_shli_tl(mask, mask, 31);
242 tcg_gen_add_tl(result, r1, r2);
243 /* Calc PSW_V */
244 tcg_gen_xor_tl(temp, result, r1);
245 tcg_gen_xor_tl(temp2, r1, r2);
246 tcg_gen_andc_tl(temp, temp, temp2);
247 tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
248 /* Set PSW_SV */
249 tcg_gen_and_tl(temp, temp, mask);
250 tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
251 /* calc AV bit */
252 tcg_gen_add_tl(temp, result, result);
253 tcg_gen_xor_tl(temp, temp, result);
254 tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
255 /* calc SAV bit */
256 tcg_gen_and_tl(temp, temp, mask);
257 tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
258 /* write back result */
259 tcg_gen_movcond_tl(cond, r3, r4, t0, result, r3);
261 tcg_temp_free(t0);
262 tcg_temp_free(temp);
263 tcg_temp_free(temp2);
264 tcg_temp_free(result);
265 tcg_temp_free(mask);
268 static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
269 TCGv r3, TCGv r4)
271 TCGv temp = tcg_const_i32(r2);
272 gen_cond_add(cond, r1, temp, r3, r4);
273 tcg_temp_free(temp);
276 static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
278 TCGv temp = tcg_temp_new_i32();
279 TCGv result = tcg_temp_new_i32();
281 tcg_gen_sub_tl(result, r1, r2);
282 /* calc V bit */
283 tcg_gen_xor_tl(cpu_PSW_V, result, r1);
284 tcg_gen_xor_tl(temp, r1, r2);
285 tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
286 /* calc SV bit */
287 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
288 /* Calc AV bit */
289 tcg_gen_add_tl(cpu_PSW_AV, result, result);
290 tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
291 /* calc SAV bit */
292 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
293 /* write back result */
294 tcg_gen_mov_tl(ret, result);
296 tcg_temp_free(temp);
297 tcg_temp_free(result);
300 static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
302 TCGv high = tcg_temp_new();
303 TCGv low = tcg_temp_new();
305 tcg_gen_muls2_tl(low, high, r1, r2);
306 tcg_gen_mov_tl(ret, low);
307 /* calc V bit */
308 tcg_gen_sari_tl(low, low, 31);
309 tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
310 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
311 /* calc SV bit */
312 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
313 /* Calc AV bit */
314 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
315 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
316 /* calc SAV bit */
317 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
319 tcg_temp_free(high);
320 tcg_temp_free(low);
323 static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
325 TCGv sat_neg = tcg_const_i32(low);
326 TCGv temp = tcg_const_i32(up);
328 /* sat_neg = (arg < low ) ? low : arg; */
329 tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
331 /* ret = (sat_neg > up ) ? up : sat_neg; */
332 tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
334 tcg_temp_free(sat_neg);
335 tcg_temp_free(temp);
338 static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
340 TCGv temp = tcg_const_i32(up);
341 /* sat_neg = (arg > up ) ? up : arg; */
342 tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
343 tcg_temp_free(temp);
346 static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
348 if (shift_count == -32) {
349 tcg_gen_movi_tl(ret, 0);
350 } else if (shift_count >= 0) {
351 tcg_gen_shli_tl(ret, r1, shift_count);
352 } else {
353 tcg_gen_shri_tl(ret, r1, -shift_count);
357 static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
359 uint32_t msk, msk_start;
360 TCGv temp = tcg_temp_new();
361 TCGv temp2 = tcg_temp_new();
362 TCGv t_0 = tcg_const_i32(0);
364 if (shift_count == 0) {
365 /* Clear PSW.C and PSW.V */
366 tcg_gen_movi_tl(cpu_PSW_C, 0);
367 tcg_gen_mov_tl(cpu_PSW_V, cpu_PSW_C);
368 tcg_gen_mov_tl(ret, r1);
369 } else if (shift_count == -32) {
370 /* set PSW.C */
371 tcg_gen_mov_tl(cpu_PSW_C, r1);
372 /* fill ret completly with sign bit */
373 tcg_gen_sari_tl(ret, r1, 31);
374 /* clear PSW.V */
375 tcg_gen_movi_tl(cpu_PSW_V, 0);
376 } else if (shift_count > 0) {
377 TCGv t_max = tcg_const_i32(0x7FFFFFFF >> shift_count);
378 TCGv t_min = tcg_const_i32(((int32_t) -0x80000000) >> shift_count);
380 /* calc carry */
381 msk_start = 32 - shift_count;
382 msk = ((1 << shift_count) - 1) << msk_start;
383 tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
384 /* calc v/sv bits */
385 tcg_gen_setcond_tl(TCG_COND_GT, temp, r1, t_max);
386 tcg_gen_setcond_tl(TCG_COND_LT, temp2, r1, t_min);
387 tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
388 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
389 /* calc sv */
390 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_V, cpu_PSW_SV);
391 /* do shift */
392 tcg_gen_shli_tl(ret, r1, shift_count);
394 tcg_temp_free(t_max);
395 tcg_temp_free(t_min);
396 } else {
397 /* clear PSW.V */
398 tcg_gen_movi_tl(cpu_PSW_V, 0);
399 /* calc carry */
400 msk = (1 << -shift_count) - 1;
401 tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
402 /* do shift */
403 tcg_gen_sari_tl(ret, r1, -shift_count);
405 /* calc av overflow bit */
406 tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
407 tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
408 /* calc sav overflow bit */
409 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
411 tcg_temp_free(temp);
412 tcg_temp_free(temp2);
413 tcg_temp_free(t_0);
416 static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
418 gen_helper_add_ssov(ret, cpu_env, r1, r2);
421 static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
423 gen_helper_sub_ssov(ret, cpu_env, r1, r2);
426 /* helpers for generating program flow micro-ops */
428 static inline void gen_save_pc(target_ulong pc)
430 tcg_gen_movi_tl(cpu_PC, pc);
433 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
435 TranslationBlock *tb;
436 tb = ctx->tb;
437 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
438 likely(!ctx->singlestep_enabled)) {
439 tcg_gen_goto_tb(n);
440 gen_save_pc(dest);
441 tcg_gen_exit_tb((uintptr_t)tb + n);
442 } else {
443 gen_save_pc(dest);
444 if (ctx->singlestep_enabled) {
445 /* raise exception debug */
447 tcg_gen_exit_tb(0);
451 static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
452 TCGv r2, int16_t address)
454 int jumpLabel;
455 jumpLabel = gen_new_label();
456 tcg_gen_brcond_tl(cond, r1, r2, jumpLabel);
458 gen_goto_tb(ctx, 1, ctx->next_pc);
460 gen_set_label(jumpLabel);
461 gen_goto_tb(ctx, 0, ctx->pc + address * 2);
464 static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1,
465 int r2, int16_t address)
467 TCGv temp = tcg_const_i32(r2);
468 gen_branch_cond(ctx, cond, r1, temp, address);
469 tcg_temp_free(temp);
472 static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
474 int l1;
475 l1 = gen_new_label();
477 tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
478 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
479 gen_goto_tb(ctx, 1, ctx->pc + offset);
480 gen_set_label(l1);
481 gen_goto_tb(ctx, 0, ctx->next_pc);
484 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
485 int r2 , int32_t constant , int32_t offset)
487 TCGv temp;
489 switch (opc) {
490 /* SB-format jumps */
491 case OPC1_16_SB_J:
492 case OPC1_32_B_J:
493 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
494 break;
495 case OPC1_16_SB_CALL:
496 gen_helper_1arg(call, ctx->next_pc);
497 gen_goto_tb(ctx, 0, ctx->pc + offset * 2);
498 break;
499 case OPC1_16_SB_JZ:
500 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
501 break;
502 case OPC1_16_SB_JNZ:
503 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
504 break;
505 /* SBC-format jumps */
506 case OPC1_16_SBC_JEQ:
507 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
508 break;
509 case OPC1_16_SBC_JNE:
510 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
511 break;
512 /* SBRN-format jumps */
513 case OPC1_16_SBRN_JZ_T:
514 temp = tcg_temp_new();
515 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
516 gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
517 tcg_temp_free(temp);
518 break;
519 case OPC1_16_SBRN_JNZ_T:
520 temp = tcg_temp_new();
521 tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
522 gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
523 tcg_temp_free(temp);
524 break;
525 /* SBR-format jumps */
526 case OPC1_16_SBR_JEQ:
527 gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
528 offset);
529 break;
530 case OPC1_16_SBR_JNE:
531 gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
532 offset);
533 break;
534 case OPC1_16_SBR_JNZ:
535 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
536 break;
537 case OPC1_16_SBR_JNZ_A:
538 gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
539 break;
540 case OPC1_16_SBR_JGEZ:
541 gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
542 break;
543 case OPC1_16_SBR_JGTZ:
544 gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
545 break;
546 case OPC1_16_SBR_JLEZ:
547 gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
548 break;
549 case OPC1_16_SBR_JLTZ:
550 gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
551 break;
552 case OPC1_16_SBR_JZ:
553 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
554 break;
555 case OPC1_16_SBR_JZ_A:
556 gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
557 break;
558 case OPC1_16_SBR_LOOP:
559 gen_loop(ctx, r1, offset * 2 - 32);
560 break;
561 /* SR-format jumps */
562 case OPC1_16_SR_JI:
563 tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
564 tcg_gen_exit_tb(0);
565 break;
566 case OPC2_16_SR_RET:
567 gen_helper_ret(cpu_env);
568 tcg_gen_exit_tb(0);
569 break;
570 default:
571 printf("Branch Error at %x\n", ctx->pc);
573 ctx->bstate = BS_BRANCH;
578 * Functions for decoding instructions
581 static void decode_src_opc(DisasContext *ctx, int op1)
583 int r1;
584 int32_t const4;
585 TCGv temp, temp2;
587 r1 = MASK_OP_SRC_S1D(ctx->opcode);
588 const4 = MASK_OP_SRC_CONST4_SEXT(ctx->opcode);
590 switch (op1) {
591 case OPC1_16_SRC_ADD:
592 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
593 break;
594 case OPC1_16_SRC_ADD_A15:
595 gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[15], const4);
596 break;
597 case OPC1_16_SRC_ADD_15A:
598 gen_addi_d(cpu_gpr_d[15], cpu_gpr_d[r1], const4);
599 break;
600 case OPC1_16_SRC_ADD_A:
601 tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], const4);
602 break;
603 case OPC1_16_SRC_CADD:
604 gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
605 cpu_gpr_d[15]);
606 break;
607 case OPC1_16_SRC_CADDN:
608 gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
609 cpu_gpr_d[15]);
610 break;
611 case OPC1_16_SRC_CMOV:
612 temp = tcg_const_tl(0);
613 temp2 = tcg_const_tl(const4);
614 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
615 temp2, cpu_gpr_d[r1]);
616 tcg_temp_free(temp);
617 tcg_temp_free(temp2);
618 break;
619 case OPC1_16_SRC_CMOVN:
620 temp = tcg_const_tl(0);
621 temp2 = tcg_const_tl(const4);
622 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
623 temp2, cpu_gpr_d[r1]);
624 tcg_temp_free(temp);
625 tcg_temp_free(temp2);
626 break;
627 case OPC1_16_SRC_EQ:
628 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
629 const4);
630 break;
631 case OPC1_16_SRC_LT:
632 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
633 const4);
634 break;
635 case OPC1_16_SRC_MOV:
636 tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
637 break;
638 case OPC1_16_SRC_MOV_A:
639 const4 = MASK_OP_SRC_CONST4(ctx->opcode);
640 tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
641 break;
642 case OPC1_16_SRC_SH:
643 gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
644 break;
645 case OPC1_16_SRC_SHA:
646 gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
647 break;
651 static void decode_srr_opc(DisasContext *ctx, int op1)
653 int r1, r2;
654 TCGv temp;
656 r1 = MASK_OP_SRR_S1D(ctx->opcode);
657 r2 = MASK_OP_SRR_S2(ctx->opcode);
659 switch (op1) {
660 case OPC1_16_SRR_ADD:
661 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
662 break;
663 case OPC1_16_SRR_ADD_A15:
664 gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
665 break;
666 case OPC1_16_SRR_ADD_15A:
667 gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
668 break;
669 case OPC1_16_SRR_ADD_A:
670 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
671 break;
672 case OPC1_16_SRR_ADDS:
673 gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
674 break;
675 case OPC1_16_SRR_AND:
676 tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
677 break;
678 case OPC1_16_SRR_CMOV:
679 temp = tcg_const_tl(0);
680 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
681 cpu_gpr_d[r2], cpu_gpr_d[r1]);
682 tcg_temp_free(temp);
683 break;
684 case OPC1_16_SRR_CMOVN:
685 temp = tcg_const_tl(0);
686 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
687 cpu_gpr_d[r2], cpu_gpr_d[r1]);
688 tcg_temp_free(temp);
689 break;
690 case OPC1_16_SRR_EQ:
691 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
692 cpu_gpr_d[r2]);
693 break;
694 case OPC1_16_SRR_LT:
695 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
696 cpu_gpr_d[r2]);
697 break;
698 case OPC1_16_SRR_MOV:
699 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]);
700 break;
701 case OPC1_16_SRR_MOV_A:
702 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]);
703 break;
704 case OPC1_16_SRR_MOV_AA:
705 tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_a[r2]);
706 break;
707 case OPC1_16_SRR_MOV_D:
708 tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]);
709 break;
710 case OPC1_16_SRR_MUL:
711 gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
712 break;
713 case OPC1_16_SRR_OR:
714 tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
715 break;
716 case OPC1_16_SRR_SUB:
717 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
718 break;
719 case OPC1_16_SRR_SUB_A15B:
720 gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
721 break;
722 case OPC1_16_SRR_SUB_15AB:
723 gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
724 break;
725 case OPC1_16_SRR_SUBS:
726 gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
727 break;
728 case OPC1_16_SRR_XOR:
729 tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
730 break;
734 static void decode_ssr_opc(DisasContext *ctx, int op1)
736 int r1, r2;
738 r1 = MASK_OP_SSR_S1(ctx->opcode);
739 r2 = MASK_OP_SSR_S2(ctx->opcode);
741 switch (op1) {
742 case OPC1_16_SSR_ST_A:
743 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
744 break;
745 case OPC1_16_SSR_ST_A_POSTINC:
746 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
747 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
748 break;
749 case OPC1_16_SSR_ST_B:
750 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
751 break;
752 case OPC1_16_SSR_ST_B_POSTINC:
753 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
754 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
755 break;
756 case OPC1_16_SSR_ST_H:
757 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
758 break;
759 case OPC1_16_SSR_ST_H_POSTINC:
760 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
761 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
762 break;
763 case OPC1_16_SSR_ST_W:
764 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
765 break;
766 case OPC1_16_SSR_ST_W_POSTINC:
767 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
768 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
769 break;
773 static void decode_sc_opc(DisasContext *ctx, int op1)
775 int32_t const16;
777 const16 = MASK_OP_SC_CONST8(ctx->opcode);
779 switch (op1) {
780 case OPC1_16_SC_AND:
781 tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
782 break;
783 case OPC1_16_SC_BISR:
784 gen_helper_1arg(bisr, const16 & 0xff);
785 break;
786 case OPC1_16_SC_LD_A:
787 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
788 break;
789 case OPC1_16_SC_LD_W:
790 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
791 break;
792 case OPC1_16_SC_MOV:
793 tcg_gen_movi_tl(cpu_gpr_d[15], const16);
794 break;
795 case OPC1_16_SC_OR:
796 tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
797 break;
798 case OPC1_16_SC_ST_A:
799 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
800 break;
801 case OPC1_16_SC_ST_W:
802 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
803 break;
804 case OPC1_16_SC_SUB_A:
805 tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
806 break;
810 static void decode_slr_opc(DisasContext *ctx, int op1)
812 int r1, r2;
814 r1 = MASK_OP_SLR_D(ctx->opcode);
815 r2 = MASK_OP_SLR_S2(ctx->opcode);
817 switch (op1) {
818 /* SLR-format */
819 case OPC1_16_SLR_LD_A:
820 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
821 break;
822 case OPC1_16_SLR_LD_A_POSTINC:
823 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
824 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
825 break;
826 case OPC1_16_SLR_LD_BU:
827 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
828 break;
829 case OPC1_16_SLR_LD_BU_POSTINC:
830 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
831 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
832 break;
833 case OPC1_16_SLR_LD_H:
834 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
835 break;
836 case OPC1_16_SLR_LD_H_POSTINC:
837 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
838 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
839 break;
840 case OPC1_16_SLR_LD_W:
841 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
842 break;
843 case OPC1_16_SLR_LD_W_POSTINC:
844 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
845 tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
846 break;
850 static void decode_sro_opc(DisasContext *ctx, int op1)
852 int r2;
853 int32_t address;
855 r2 = MASK_OP_SRO_S2(ctx->opcode);
856 address = MASK_OP_SRO_OFF4(ctx->opcode);
858 /* SRO-format */
859 switch (op1) {
860 case OPC1_16_SRO_LD_A:
861 gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
862 break;
863 case OPC1_16_SRO_LD_BU:
864 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
865 break;
866 case OPC1_16_SRO_LD_H:
867 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
868 break;
869 case OPC1_16_SRO_LD_W:
870 gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
871 break;
872 case OPC1_16_SRO_ST_A:
873 gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
874 break;
875 case OPC1_16_SRO_ST_B:
876 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
877 break;
878 case OPC1_16_SRO_ST_H:
879 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
880 break;
881 case OPC1_16_SRO_ST_W:
882 gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
883 break;
887 static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
889 uint32_t op2;
890 op2 = MASK_OP_SR_OP2(ctx->opcode);
892 switch (op2) {
893 case OPC2_16_SR_NOP:
894 break;
895 case OPC2_16_SR_RET:
896 gen_compute_branch(ctx, op2, 0, 0, 0, 0);
897 break;
898 case OPC2_16_SR_RFE:
899 gen_helper_rfe(cpu_env);
900 tcg_gen_exit_tb(0);
901 ctx->bstate = BS_BRANCH;
902 break;
903 case OPC2_16_SR_DEBUG:
904 /* raise EXCP_DEBUG */
905 break;
909 static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx)
911 uint32_t op2;
912 uint32_t r1;
913 TCGv temp;
915 r1 = MASK_OP_SR_S1D(ctx->opcode);
916 op2 = MASK_OP_SR_OP2(ctx->opcode);
918 switch (op2) {
919 case OPC2_16_SR_RSUB:
920 /* overflow only if r1 = -0x80000000 */
921 temp = tcg_const_i32(-0x80000000);
922 /* calc V bit */
923 tcg_gen_setcond_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r1], temp);
924 tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
925 /* calc SV bit */
926 tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
927 /* sub */
928 tcg_gen_neg_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
929 /* calc av */
930 tcg_gen_add_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_gpr_d[r1]);
931 tcg_gen_xor_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_PSW_AV);
932 /* calc sav */
933 tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
934 tcg_temp_free(temp);
935 break;
936 case OPC2_16_SR_SAT_B:
937 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
938 break;
939 case OPC2_16_SR_SAT_BU:
940 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
941 break;
942 case OPC2_16_SR_SAT_H:
943 gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
944 break;
945 case OPC2_16_SR_SAT_HU:
946 gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
947 break;
951 static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
953 int op1;
954 int r1, r2;
955 int32_t const16;
956 int32_t address;
957 TCGv temp;
959 op1 = MASK_OP_MAJOR(ctx->opcode);
961 /* handle ADDSC.A opcode only being 6 bit long */
962 if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
963 op1 = OPC1_16_SRRS_ADDSC_A;
966 switch (op1) {
967 case OPC1_16_SRC_ADD:
968 case OPC1_16_SRC_ADD_A15:
969 case OPC1_16_SRC_ADD_15A:
970 case OPC1_16_SRC_ADD_A:
971 case OPC1_16_SRC_CADD:
972 case OPC1_16_SRC_CADDN:
973 case OPC1_16_SRC_CMOV:
974 case OPC1_16_SRC_CMOVN:
975 case OPC1_16_SRC_EQ:
976 case OPC1_16_SRC_LT:
977 case OPC1_16_SRC_MOV:
978 case OPC1_16_SRC_MOV_A:
979 case OPC1_16_SRC_SH:
980 case OPC1_16_SRC_SHA:
981 decode_src_opc(ctx, op1);
982 break;
983 /* SRR-format */
984 case OPC1_16_SRR_ADD:
985 case OPC1_16_SRR_ADD_A15:
986 case OPC1_16_SRR_ADD_15A:
987 case OPC1_16_SRR_ADD_A:
988 case OPC1_16_SRR_ADDS:
989 case OPC1_16_SRR_AND:
990 case OPC1_16_SRR_CMOV:
991 case OPC1_16_SRR_CMOVN:
992 case OPC1_16_SRR_EQ:
993 case OPC1_16_SRR_LT:
994 case OPC1_16_SRR_MOV:
995 case OPC1_16_SRR_MOV_A:
996 case OPC1_16_SRR_MOV_AA:
997 case OPC1_16_SRR_MOV_D:
998 case OPC1_16_SRR_MUL:
999 case OPC1_16_SRR_OR:
1000 case OPC1_16_SRR_SUB:
1001 case OPC1_16_SRR_SUB_A15B:
1002 case OPC1_16_SRR_SUB_15AB:
1003 case OPC1_16_SRR_SUBS:
1004 case OPC1_16_SRR_XOR:
1005 decode_srr_opc(ctx, op1);
1006 break;
1007 /* SSR-format */
1008 case OPC1_16_SSR_ST_A:
1009 case OPC1_16_SSR_ST_A_POSTINC:
1010 case OPC1_16_SSR_ST_B:
1011 case OPC1_16_SSR_ST_B_POSTINC:
1012 case OPC1_16_SSR_ST_H:
1013 case OPC1_16_SSR_ST_H_POSTINC:
1014 case OPC1_16_SSR_ST_W:
1015 case OPC1_16_SSR_ST_W_POSTINC:
1016 decode_ssr_opc(ctx, op1);
1017 break;
1018 /* SRRS-format */
1019 case OPC1_16_SRRS_ADDSC_A:
1020 r2 = MASK_OP_SRRS_S2(ctx->opcode);
1021 r1 = MASK_OP_SRRS_S1D(ctx->opcode);
1022 const16 = MASK_OP_SRRS_N(ctx->opcode);
1023 temp = tcg_temp_new();
1024 tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
1025 tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
1026 tcg_temp_free(temp);
1027 break;
1028 /* SLRO-format */
1029 case OPC1_16_SLRO_LD_A:
1030 r1 = MASK_OP_SLRO_D(ctx->opcode);
1031 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
1032 gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
1033 break;
1034 case OPC1_16_SLRO_LD_BU:
1035 r1 = MASK_OP_SLRO_D(ctx->opcode);
1036 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
1037 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
1038 break;
1039 case OPC1_16_SLRO_LD_H:
1040 r1 = MASK_OP_SLRO_D(ctx->opcode);
1041 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
1042 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
1043 break;
1044 case OPC1_16_SLRO_LD_W:
1045 r1 = MASK_OP_SLRO_D(ctx->opcode);
1046 const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
1047 gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
1048 break;
1049 /* SB-format */
1050 case OPC1_16_SB_CALL:
1051 case OPC1_16_SB_J:
1052 case OPC1_16_SB_JNZ:
1053 case OPC1_16_SB_JZ:
1054 address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
1055 gen_compute_branch(ctx, op1, 0, 0, 0, address);
1056 break;
1057 /* SBC-format */
1058 case OPC1_16_SBC_JEQ:
1059 case OPC1_16_SBC_JNE:
1060 address = MASK_OP_SBC_DISP4(ctx->opcode);
1061 const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
1062 gen_compute_branch(ctx, op1, 0, 0, const16, address);
1063 break;
1064 /* SBRN-format */
1065 case OPC1_16_SBRN_JNZ_T:
1066 case OPC1_16_SBRN_JZ_T:
1067 address = MASK_OP_SBRN_DISP4(ctx->opcode);
1068 const16 = MASK_OP_SBRN_N(ctx->opcode);
1069 gen_compute_branch(ctx, op1, 0, 0, const16, address);
1070 break;
1071 /* SBR-format */
1072 case OPC1_16_SBR_JEQ:
1073 case OPC1_16_SBR_JGEZ:
1074 case OPC1_16_SBR_JGTZ:
1075 case OPC1_16_SBR_JLEZ:
1076 case OPC1_16_SBR_JLTZ:
1077 case OPC1_16_SBR_JNE:
1078 case OPC1_16_SBR_JNZ:
1079 case OPC1_16_SBR_JNZ_A:
1080 case OPC1_16_SBR_JZ:
1081 case OPC1_16_SBR_JZ_A:
1082 case OPC1_16_SBR_LOOP:
1083 r1 = MASK_OP_SBR_S2(ctx->opcode);
1084 address = MASK_OP_SBR_DISP4(ctx->opcode);
1085 gen_compute_branch(ctx, op1, r1, 0, 0, address);
1086 break;
1087 /* SC-format */
1088 case OPC1_16_SC_AND:
1089 case OPC1_16_SC_BISR:
1090 case OPC1_16_SC_LD_A:
1091 case OPC1_16_SC_LD_W:
1092 case OPC1_16_SC_MOV:
1093 case OPC1_16_SC_OR:
1094 case OPC1_16_SC_ST_A:
1095 case OPC1_16_SC_ST_W:
1096 case OPC1_16_SC_SUB_A:
1097 decode_sc_opc(ctx, op1);
1098 break;
1099 /* SLR-format */
1100 case OPC1_16_SLR_LD_A:
1101 case OPC1_16_SLR_LD_A_POSTINC:
1102 case OPC1_16_SLR_LD_BU:
1103 case OPC1_16_SLR_LD_BU_POSTINC:
1104 case OPC1_16_SLR_LD_H:
1105 case OPC1_16_SLR_LD_H_POSTINC:
1106 case OPC1_16_SLR_LD_W:
1107 case OPC1_16_SLR_LD_W_POSTINC:
1108 decode_slr_opc(ctx, op1);
1109 break;
1110 /* SRO-format */
1111 case OPC1_16_SRO_LD_A:
1112 case OPC1_16_SRO_LD_BU:
1113 case OPC1_16_SRO_LD_H:
1114 case OPC1_16_SRO_LD_W:
1115 case OPC1_16_SRO_ST_A:
1116 case OPC1_16_SRO_ST_B:
1117 case OPC1_16_SRO_ST_H:
1118 case OPC1_16_SRO_ST_W:
1119 decode_sro_opc(ctx, op1);
1120 break;
1121 /* SSRO-format */
1122 case OPC1_16_SSRO_ST_A:
1123 r1 = MASK_OP_SSRO_S1(ctx->opcode);
1124 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
1125 gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
1126 break;
1127 case OPC1_16_SSRO_ST_B:
1128 r1 = MASK_OP_SSRO_S1(ctx->opcode);
1129 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
1130 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
1131 break;
1132 case OPC1_16_SSRO_ST_H:
1133 r1 = MASK_OP_SSRO_S1(ctx->opcode);
1134 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
1135 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
1136 break;
1137 case OPC1_16_SSRO_ST_W:
1138 r1 = MASK_OP_SSRO_S1(ctx->opcode);
1139 const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
1140 gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
1141 break;
1142 /* SR-format */
1143 case OPCM_16_SR_SYSTEM:
1144 decode_sr_system(env, ctx);
1145 break;
1146 case OPCM_16_SR_ACCU:
1147 decode_sr_accu(env, ctx);
1148 break;
1149 case OPC1_16_SR_JI:
1150 r1 = MASK_OP_SR_S1D(ctx->opcode);
1151 gen_compute_branch(ctx, op1, r1, 0, 0, 0);
1152 break;
1153 case OPC1_16_SR_NOT:
1154 r1 = MASK_OP_SR_S1D(ctx->opcode);
1155 tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
1156 break;
1161 * 32 bit instructions
1164 /* ABS-format */
1165 static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx)
1167 int32_t op2;
1168 int32_t r1;
1169 uint32_t address;
1170 TCGv temp;
1172 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1173 address = MASK_OP_ABS_OFF18(ctx->opcode);
1174 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1176 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1178 switch (op2) {
1179 case OPC2_32_ABS_LD_A:
1180 tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
1181 break;
1182 case OPC2_32_ABS_LD_D:
1183 gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
1184 break;
1185 case OPC2_32_ABS_LD_DA:
1186 gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
1187 break;
1188 case OPC2_32_ABS_LD_W:
1189 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
1190 break;
1193 tcg_temp_free(temp);
1196 static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx)
1198 int32_t op2;
1199 int32_t r1;
1200 uint32_t address;
1201 TCGv temp;
1203 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1204 address = MASK_OP_ABS_OFF18(ctx->opcode);
1205 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1207 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1209 switch (op2) {
1210 case OPC2_32_ABS_LD_B:
1211 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB);
1212 break;
1213 case OPC2_32_ABS_LD_BU:
1214 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
1215 break;
1216 case OPC2_32_ABS_LD_H:
1217 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW);
1218 break;
1219 case OPC2_32_ABS_LD_HU:
1220 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
1221 break;
1224 tcg_temp_free(temp);
1227 static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx)
1229 int32_t op2;
1230 int32_t r1;
1231 uint32_t address;
1232 TCGv temp;
1234 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1235 address = MASK_OP_ABS_OFF18(ctx->opcode);
1236 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1238 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1240 switch (op2) {
1241 case OPC2_32_ABS_LDMST:
1242 gen_ldmst(ctx, r1, temp);
1243 break;
1244 case OPC2_32_ABS_SWAP_W:
1245 gen_swap(ctx, r1, temp);
1246 break;
1249 tcg_temp_free(temp);
1252 static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx)
1254 uint32_t op2;
1255 int32_t off18;
1257 off18 = MASK_OP_ABS_OFF18(ctx->opcode);
1258 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1260 switch (op2) {
1261 case OPC2_32_ABS_LDLCX:
1262 gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18));
1263 break;
1264 case OPC2_32_ABS_LDUCX:
1265 gen_helper_1arg(lducx, EA_ABS_FORMAT(off18));
1266 break;
1267 case OPC2_32_ABS_STLCX:
1268 gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18));
1269 break;
1270 case OPC2_32_ABS_STUCX:
1271 gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
1272 break;
1276 static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx)
1278 int32_t op2;
1279 int32_t r1;
1280 uint32_t address;
1281 TCGv temp;
1283 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1284 address = MASK_OP_ABS_OFF18(ctx->opcode);
1285 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1287 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1289 switch (op2) {
1290 case OPC2_32_ABS_ST_A:
1291 tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
1292 break;
1293 case OPC2_32_ABS_ST_D:
1294 gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
1295 break;
1296 case OPC2_32_ABS_ST_DA:
1297 gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
1298 break;
1299 case OPC2_32_ABS_ST_W:
1300 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
1301 break;
1304 tcg_temp_free(temp);
1307 static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx)
1309 int32_t op2;
1310 int32_t r1;
1311 uint32_t address;
1312 TCGv temp;
1314 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1315 address = MASK_OP_ABS_OFF18(ctx->opcode);
1316 op2 = MASK_OP_ABS_OP2(ctx->opcode);
1318 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1320 switch (op2) {
1321 case OPC2_32_ABS_ST_B:
1322 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
1323 break;
1324 case OPC2_32_ABS_ST_H:
1325 tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
1326 break;
1328 tcg_temp_free(temp);
1331 static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
1333 int op1;
1334 int32_t r1;
1335 int32_t address;
1336 int8_t b;
1337 int32_t bpos;
1338 TCGv temp, temp2;
1340 op1 = MASK_OP_MAJOR(ctx->opcode);
1342 switch (op1) {
1343 /* ABS-format */
1344 case OPCM_32_ABS_LDW:
1345 decode_abs_ldw(env, ctx);
1346 break;
1347 case OPCM_32_ABS_LDB:
1348 decode_abs_ldb(env, ctx);
1349 break;
1350 case OPCM_32_ABS_LDMST_SWAP:
1351 decode_abs_ldst_swap(env, ctx);
1352 break;
1353 case OPCM_32_ABS_LDST_CONTEXT:
1354 decode_abs_ldst_context(env, ctx);
1355 break;
1356 case OPCM_32_ABS_STORE:
1357 decode_abs_store(env, ctx);
1358 break;
1359 case OPCM_32_ABS_STOREB_H:
1360 decode_abs_storeb_h(env, ctx);
1361 break;
1362 case OPC1_32_ABS_STOREQ:
1363 address = MASK_OP_ABS_OFF18(ctx->opcode);
1364 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1365 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1366 temp2 = tcg_temp_new();
1368 tcg_gen_shri_tl(temp2, cpu_gpr_d[r1], 16);
1369 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_LEUW);
1371 tcg_temp_free(temp2);
1372 tcg_temp_free(temp);
1373 break;
1374 case OPC1_32_ABS_LD_Q:
1375 address = MASK_OP_ABS_OFF18(ctx->opcode);
1376 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1377 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1379 tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
1380 tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
1382 tcg_temp_free(temp);
1383 break;
1384 case OPC1_32_ABS_LEA:
1385 address = MASK_OP_ABS_OFF18(ctx->opcode);
1386 r1 = MASK_OP_ABS_S1D(ctx->opcode);
1387 tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address));
1388 break;
1389 /* ABSB-format */
1390 case OPC1_32_ABSB_ST_T:
1391 address = MASK_OP_ABS_OFF18(ctx->opcode);
1392 b = MASK_OP_ABSB_B(ctx->opcode);
1393 bpos = MASK_OP_ABSB_BPOS(ctx->opcode);
1395 temp = tcg_const_i32(EA_ABS_FORMAT(address));
1396 temp2 = tcg_temp_new();
1398 tcg_gen_qemu_ld_tl(temp2, temp, ctx->mem_idx, MO_UB);
1399 tcg_gen_andi_tl(temp2, temp2, ~(0x1u << bpos));
1400 tcg_gen_ori_tl(temp2, temp2, (b << bpos));
1401 tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_UB);
1403 tcg_temp_free(temp);
1404 tcg_temp_free(temp2);
1405 break;
1409 static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
1411 /* 16-Bit Instruction */
1412 if ((ctx->opcode & 0x1) == 0) {
1413 ctx->next_pc = ctx->pc + 2;
1414 decode_16Bit_opc(env, ctx);
1415 /* 32-Bit Instruction */
1416 } else {
1417 ctx->next_pc = ctx->pc + 4;
1418 decode_32Bit_opc(env, ctx);
1422 static inline void
1423 gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
1424 int search_pc)
1426 CPUState *cs = CPU(cpu);
1427 CPUTriCoreState *env = &cpu->env;
1428 DisasContext ctx;
1429 target_ulong pc_start;
1430 int num_insns;
1431 uint16_t *gen_opc_end;
1433 if (search_pc) {
1434 qemu_log("search pc %d\n", search_pc);
1437 num_insns = 0;
1438 pc_start = tb->pc;
1439 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
1440 ctx.pc = pc_start;
1441 ctx.saved_pc = -1;
1442 ctx.tb = tb;
1443 ctx.singlestep_enabled = cs->singlestep_enabled;
1444 ctx.bstate = BS_NONE;
1445 ctx.mem_idx = cpu_mmu_index(env);
1447 tcg_clear_temp_count();
1448 gen_tb_start();
1449 while (ctx.bstate == BS_NONE) {
1450 ctx.opcode = cpu_ldl_code(env, ctx.pc);
1451 decode_opc(env, &ctx, 0);
1453 num_insns++;
1455 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
1456 gen_save_pc(ctx.next_pc);
1457 tcg_gen_exit_tb(0);
1458 break;
1460 if (singlestep) {
1461 gen_save_pc(ctx.next_pc);
1462 tcg_gen_exit_tb(0);
1463 break;
1465 ctx.pc = ctx.next_pc;
1468 gen_tb_end(tb, num_insns);
1469 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
1470 if (search_pc) {
1471 printf("done_generating search pc\n");
1472 } else {
1473 tb->size = ctx.pc - pc_start;
1474 tb->icount = num_insns;
1476 if (tcg_check_temp_count()) {
1477 printf("LEAK at %08x\n", env->PC);
1480 #ifdef DEBUG_DISAS
1481 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1482 qemu_log("IN: %s\n", lookup_symbol(pc_start));
1483 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
1484 qemu_log("\n");
1486 #endif
1489 void
1490 gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
1492 gen_intermediate_code_internal(tricore_env_get_cpu(env), tb, false);
1495 void
1496 gen_intermediate_code_pc(CPUTriCoreState *env, struct TranslationBlock *tb)
1498 gen_intermediate_code_internal(tricore_env_get_cpu(env), tb, true);
1501 void
1502 restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb, int pc_pos)
1504 env->PC = tcg_ctx.gen_opc_pc[pc_pos];
1508 * Initialization
1512 void cpu_state_reset(CPUTriCoreState *env)
1514 /* Reset Regs to Default Value */
1515 env->PSW = 0xb80;
1518 static void tricore_tcg_init_csfr(void)
1520 cpu_PCXI = tcg_global_mem_new(TCG_AREG0,
1521 offsetof(CPUTriCoreState, PCXI), "PCXI");
1522 cpu_PSW = tcg_global_mem_new(TCG_AREG0,
1523 offsetof(CPUTriCoreState, PSW), "PSW");
1524 cpu_PC = tcg_global_mem_new(TCG_AREG0,
1525 offsetof(CPUTriCoreState, PC), "PC");
1526 cpu_ICR = tcg_global_mem_new(TCG_AREG0,
1527 offsetof(CPUTriCoreState, ICR), "ICR");
1530 void tricore_tcg_init(void)
1532 int i;
1533 static int inited;
1534 if (inited) {
1535 return;
1537 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1538 /* reg init */
1539 for (i = 0 ; i < 16 ; i++) {
1540 cpu_gpr_a[i] = tcg_global_mem_new(TCG_AREG0,
1541 offsetof(CPUTriCoreState, gpr_a[i]),
1542 regnames_a[i]);
1544 for (i = 0 ; i < 16 ; i++) {
1545 cpu_gpr_d[i] = tcg_global_mem_new(TCG_AREG0,
1546 offsetof(CPUTriCoreState, gpr_d[i]),
1547 regnames_d[i]);
1549 tricore_tcg_init_csfr();
1550 /* init PSW flag cache */
1551 cpu_PSW_C = tcg_global_mem_new(TCG_AREG0,
1552 offsetof(CPUTriCoreState, PSW_USB_C),
1553 "PSW_C");
1554 cpu_PSW_V = tcg_global_mem_new(TCG_AREG0,
1555 offsetof(CPUTriCoreState, PSW_USB_V),
1556 "PSW_V");
1557 cpu_PSW_SV = tcg_global_mem_new(TCG_AREG0,
1558 offsetof(CPUTriCoreState, PSW_USB_SV),
1559 "PSW_SV");
1560 cpu_PSW_AV = tcg_global_mem_new(TCG_AREG0,
1561 offsetof(CPUTriCoreState, PSW_USB_AV),
1562 "PSW_AV");
1563 cpu_PSW_SAV = tcg_global_mem_new(TCG_AREG0,
1564 offsetof(CPUTriCoreState, PSW_USB_SAV),
1565 "PSW_SAV");