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/>.
22 #include "disas/disas.h"
24 #include "exec/cpu_ldst.h"
26 #include "exec/helper-proto.h"
27 #include "exec/helper-gen.h"
29 #include "tricore-opcodes.h"
39 static TCGv cpu_gpr_a
[16];
40 static TCGv cpu_gpr_d
[16];
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
;
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
;
68 int singlestep_enabled
;
69 /* Routine used to access memory */
71 uint32_t hflags
, saved_hflags
;
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
;
90 cpu_fprintf(f
, "PC=%08x\n", env
->PC
);
91 for (i
= 0; i
< 16; ++i
) {
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
) {
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); \
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
);
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
);
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
);
179 tcg_temp_free(temp2
);
182 /* tmp = M(EA, word);
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
);
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
);
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
);
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
);
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
);
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
);
229 static inline void gen_cond_add(TCGCond cond
, TCGv r1
, TCGv r2
, TCGv r3
,
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
);
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
);
249 tcg_gen_and_tl(temp
, temp
, mask
);
250 tcg_gen_or_tl(cpu_PSW_SV
, temp
, cpu_PSW_SV
);
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
);
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
);
263 tcg_temp_free(temp2
);
264 tcg_temp_free(result
);
268 static inline void gen_condi_add(TCGCond cond
, TCGv r1
, int32_t r2
,
271 TCGv temp
= tcg_const_i32(r2
);
272 gen_cond_add(cond
, r1
, temp
, r3
, r4
);
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
);
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
);
287 tcg_gen_or_tl(cpu_PSW_SV
, cpu_PSW_SV
, cpu_PSW_V
);
289 tcg_gen_add_tl(cpu_PSW_AV
, result
, result
);
290 tcg_gen_xor_tl(cpu_PSW_AV
, result
, cpu_PSW_AV
);
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
);
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
);
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);
312 tcg_gen_or_tl(cpu_PSW_SV
, cpu_PSW_SV
, cpu_PSW_V
);
314 tcg_gen_add_tl(cpu_PSW_AV
, ret
, ret
);
315 tcg_gen_xor_tl(cpu_PSW_AV
, ret
, cpu_PSW_AV
);
317 tcg_gen_or_tl(cpu_PSW_SAV
, cpu_PSW_SAV
, cpu_PSW_AV
);
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
);
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
);
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
);
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) {
371 tcg_gen_mov_tl(cpu_PSW_C
, r1
);
372 /* fill ret completly with sign bit */
373 tcg_gen_sari_tl(ret
, r1
, 31);
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
);
381 msk_start
= 32 - shift_count
;
382 msk
= ((1 << shift_count
) - 1) << msk_start
;
383 tcg_gen_andi_tl(cpu_PSW_C
, r1
, msk
);
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);
390 tcg_gen_or_tl(cpu_PSW_SV
, cpu_PSW_V
, cpu_PSW_SV
);
392 tcg_gen_shli_tl(ret
, r1
, shift_count
);
394 tcg_temp_free(t_max
);
395 tcg_temp_free(t_min
);
398 tcg_gen_movi_tl(cpu_PSW_V
, 0);
400 msk
= (1 << -shift_count
) - 1;
401 tcg_gen_andi_tl(cpu_PSW_C
, r1
, msk
);
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
);
412 tcg_temp_free(temp2
);
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
;
437 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
438 likely(!ctx
->singlestep_enabled
)) {
441 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
444 if (ctx
->singlestep_enabled
) {
445 /* raise exception debug */
451 static inline void gen_branch_cond(DisasContext
*ctx
, TCGCond cond
, TCGv r1
,
452 TCGv r2
, int16_t address
)
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
);
472 static void gen_loop(DisasContext
*ctx
, int r1
, int32_t offset
)
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
);
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
)
490 /* SB-format jumps */
493 gen_goto_tb(ctx
, 0, ctx
->pc
+ offset
* 2);
495 case OPC1_16_SB_CALL
:
496 gen_helper_1arg(call
, ctx
->next_pc
);
497 gen_goto_tb(ctx
, 0, ctx
->pc
+ offset
* 2);
500 gen_branch_condi(ctx
, TCG_COND_EQ
, cpu_gpr_d
[15], 0, offset
);
503 gen_branch_condi(ctx
, TCG_COND_NE
, cpu_gpr_d
[15], 0, offset
);
505 /* SBC-format jumps */
506 case OPC1_16_SBC_JEQ
:
507 gen_branch_condi(ctx
, TCG_COND_EQ
, cpu_gpr_d
[15], constant
, offset
);
509 case OPC1_16_SBC_JNE
:
510 gen_branch_condi(ctx
, TCG_COND_NE
, cpu_gpr_d
[15], constant
, offset
);
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
);
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
);
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],
530 case OPC1_16_SBR_JNE
:
531 gen_branch_cond(ctx
, TCG_COND_NE
, cpu_gpr_d
[r1
], cpu_gpr_d
[15],
534 case OPC1_16_SBR_JNZ
:
535 gen_branch_condi(ctx
, TCG_COND_NE
, cpu_gpr_d
[r1
], 0, offset
);
537 case OPC1_16_SBR_JNZ_A
:
538 gen_branch_condi(ctx
, TCG_COND_NE
, cpu_gpr_a
[r1
], 0, offset
);
540 case OPC1_16_SBR_JGEZ
:
541 gen_branch_condi(ctx
, TCG_COND_GE
, cpu_gpr_d
[r1
], 0, offset
);
543 case OPC1_16_SBR_JGTZ
:
544 gen_branch_condi(ctx
, TCG_COND_GT
, cpu_gpr_d
[r1
], 0, offset
);
546 case OPC1_16_SBR_JLEZ
:
547 gen_branch_condi(ctx
, TCG_COND_LE
, cpu_gpr_d
[r1
], 0, offset
);
549 case OPC1_16_SBR_JLTZ
:
550 gen_branch_condi(ctx
, TCG_COND_LT
, cpu_gpr_d
[r1
], 0, offset
);
553 gen_branch_condi(ctx
, TCG_COND_EQ
, cpu_gpr_d
[r1
], 0, offset
);
555 case OPC1_16_SBR_JZ_A
:
556 gen_branch_condi(ctx
, TCG_COND_EQ
, cpu_gpr_a
[r1
], 0, offset
);
558 case OPC1_16_SBR_LOOP
:
559 gen_loop(ctx
, r1
, offset
* 2 - 32);
561 /* SR-format jumps */
563 tcg_gen_andi_tl(cpu_PC
, cpu_gpr_a
[r1
], 0xfffffffe);
567 gen_helper_ret(cpu_env
);
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
)
587 r1
= MASK_OP_SRC_S1D(ctx
->opcode
);
588 const4
= MASK_OP_SRC_CONST4_SEXT(ctx
->opcode
);
591 case OPC1_16_SRC_ADD
:
592 gen_addi_d(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], const4
);
594 case OPC1_16_SRC_ADD_A15
:
595 gen_addi_d(cpu_gpr_d
[r1
], cpu_gpr_d
[15], const4
);
597 case OPC1_16_SRC_ADD_15A
:
598 gen_addi_d(cpu_gpr_d
[15], cpu_gpr_d
[r1
], const4
);
600 case OPC1_16_SRC_ADD_A
:
601 tcg_gen_addi_tl(cpu_gpr_a
[r1
], cpu_gpr_a
[r1
], const4
);
603 case OPC1_16_SRC_CADD
:
604 gen_condi_add(TCG_COND_NE
, cpu_gpr_d
[r1
], const4
, cpu_gpr_d
[r1
],
607 case OPC1_16_SRC_CADDN
:
608 gen_condi_add(TCG_COND_EQ
, cpu_gpr_d
[r1
], const4
, cpu_gpr_d
[r1
],
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
]);
617 tcg_temp_free(temp2
);
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
]);
625 tcg_temp_free(temp2
);
628 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_gpr_d
[15], cpu_gpr_d
[r1
],
632 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr_d
[15], cpu_gpr_d
[r1
],
635 case OPC1_16_SRC_MOV
:
636 tcg_gen_movi_tl(cpu_gpr_d
[r1
], const4
);
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
);
643 gen_shi(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], const4
);
645 case OPC1_16_SRC_SHA
:
646 gen_shaci(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], const4
);
651 static void decode_srr_opc(DisasContext
*ctx
, int op1
)
656 r1
= MASK_OP_SRR_S1D(ctx
->opcode
);
657 r2
= MASK_OP_SRR_S2(ctx
->opcode
);
660 case OPC1_16_SRR_ADD
:
661 gen_add_d(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
663 case OPC1_16_SRR_ADD_A15
:
664 gen_add_d(cpu_gpr_d
[r1
], cpu_gpr_d
[15], cpu_gpr_d
[r2
]);
666 case OPC1_16_SRR_ADD_15A
:
667 gen_add_d(cpu_gpr_d
[15], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
669 case OPC1_16_SRR_ADD_A
:
670 tcg_gen_add_tl(cpu_gpr_a
[r1
], cpu_gpr_a
[r1
], cpu_gpr_a
[r2
]);
672 case OPC1_16_SRR_ADDS
:
673 gen_adds(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
675 case OPC1_16_SRR_AND
:
676 tcg_gen_and_tl(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
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
]);
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
]);
691 tcg_gen_setcond_tl(TCG_COND_EQ
, cpu_gpr_d
[15], cpu_gpr_d
[r1
],
695 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr_d
[15], cpu_gpr_d
[r1
],
698 case OPC1_16_SRR_MOV
:
699 tcg_gen_mov_tl(cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
701 case OPC1_16_SRR_MOV_A
:
702 tcg_gen_mov_tl(cpu_gpr_a
[r1
], cpu_gpr_d
[r2
]);
704 case OPC1_16_SRR_MOV_AA
:
705 tcg_gen_mov_tl(cpu_gpr_a
[r1
], cpu_gpr_a
[r2
]);
707 case OPC1_16_SRR_MOV_D
:
708 tcg_gen_mov_tl(cpu_gpr_d
[r1
], cpu_gpr_a
[r2
]);
710 case OPC1_16_SRR_MUL
:
711 gen_mul_i32s(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
714 tcg_gen_or_tl(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
716 case OPC1_16_SRR_SUB
:
717 gen_sub_d(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
719 case OPC1_16_SRR_SUB_A15B
:
720 gen_sub_d(cpu_gpr_d
[r1
], cpu_gpr_d
[15], cpu_gpr_d
[r2
]);
722 case OPC1_16_SRR_SUB_15AB
:
723 gen_sub_d(cpu_gpr_d
[15], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
725 case OPC1_16_SRR_SUBS
:
726 gen_subs(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
728 case OPC1_16_SRR_XOR
:
729 tcg_gen_xor_tl(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], cpu_gpr_d
[r2
]);
734 static void decode_ssr_opc(DisasContext
*ctx
, int op1
)
738 r1
= MASK_OP_SSR_S1(ctx
->opcode
);
739 r2
= MASK_OP_SSR_S2(ctx
->opcode
);
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
);
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);
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
);
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);
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
);
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);
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
);
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);
773 static void decode_sc_opc(DisasContext
*ctx
, int op1
)
777 const16
= MASK_OP_SC_CONST8(ctx
->opcode
);
781 tcg_gen_andi_tl(cpu_gpr_d
[15], cpu_gpr_d
[15], const16
);
783 case OPC1_16_SC_BISR
:
784 gen_helper_1arg(bisr
, const16
& 0xff);
786 case OPC1_16_SC_LD_A
:
787 gen_offset_ld(ctx
, cpu_gpr_a
[15], cpu_gpr_a
[10], const16
* 4, MO_LESL
);
789 case OPC1_16_SC_LD_W
:
790 gen_offset_ld(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[10], const16
* 4, MO_LESL
);
793 tcg_gen_movi_tl(cpu_gpr_d
[15], const16
);
796 tcg_gen_ori_tl(cpu_gpr_d
[15], cpu_gpr_d
[15], const16
);
798 case OPC1_16_SC_ST_A
:
799 gen_offset_st(ctx
, cpu_gpr_a
[15], cpu_gpr_a
[10], const16
* 4, MO_LESL
);
801 case OPC1_16_SC_ST_W
:
802 gen_offset_st(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[10], const16
* 4, MO_LESL
);
804 case OPC1_16_SC_SUB_A
:
805 tcg_gen_subi_tl(cpu_gpr_a
[10], cpu_gpr_a
[10], const16
);
810 static void decode_slr_opc(DisasContext
*ctx
, int op1
)
814 r1
= MASK_OP_SLR_D(ctx
->opcode
);
815 r2
= MASK_OP_SLR_S2(ctx
->opcode
);
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
);
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);
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
);
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);
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
);
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);
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
);
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);
850 static void decode_sro_opc(DisasContext
*ctx
, int op1
)
855 r2
= MASK_OP_SRO_S2(ctx
->opcode
);
856 address
= MASK_OP_SRO_OFF4(ctx
->opcode
);
860 case OPC1_16_SRO_LD_A
:
861 gen_offset_ld(ctx
, cpu_gpr_a
[15], cpu_gpr_a
[r2
], address
* 4, MO_LESL
);
863 case OPC1_16_SRO_LD_BU
:
864 gen_offset_ld(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
, MO_UB
);
866 case OPC1_16_SRO_LD_H
:
867 gen_offset_ld(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
, MO_LESW
);
869 case OPC1_16_SRO_LD_W
:
870 gen_offset_ld(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
* 4, MO_LESL
);
872 case OPC1_16_SRO_ST_A
:
873 gen_offset_st(ctx
, cpu_gpr_a
[15], cpu_gpr_a
[r2
], address
* 4, MO_LESL
);
875 case OPC1_16_SRO_ST_B
:
876 gen_offset_st(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
, MO_UB
);
878 case OPC1_16_SRO_ST_H
:
879 gen_offset_st(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
* 2, MO_LESW
);
881 case OPC1_16_SRO_ST_W
:
882 gen_offset_st(ctx
, cpu_gpr_d
[15], cpu_gpr_a
[r2
], address
* 4, MO_LESL
);
887 static void decode_sr_system(CPUTriCoreState
*env
, DisasContext
*ctx
)
890 op2
= MASK_OP_SR_OP2(ctx
->opcode
);
896 gen_compute_branch(ctx
, op2
, 0, 0, 0, 0);
899 gen_helper_rfe(cpu_env
);
901 ctx
->bstate
= BS_BRANCH
;
903 case OPC2_16_SR_DEBUG
:
904 /* raise EXCP_DEBUG */
909 static void decode_sr_accu(CPUTriCoreState
*env
, DisasContext
*ctx
)
915 r1
= MASK_OP_SR_S1D(ctx
->opcode
);
916 op2
= MASK_OP_SR_OP2(ctx
->opcode
);
919 case OPC2_16_SR_RSUB
:
920 /* overflow only if r1 = -0x80000000 */
921 temp
= tcg_const_i32(-0x80000000);
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);
926 tcg_gen_or_tl(cpu_PSW_SV
, cpu_PSW_SV
, cpu_PSW_V
);
928 tcg_gen_neg_tl(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
]);
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
);
933 tcg_gen_or_tl(cpu_PSW_SAV
, cpu_PSW_SAV
, cpu_PSW_AV
);
936 case OPC2_16_SR_SAT_B
:
937 gen_saturate(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], 0x7f, -0x80);
939 case OPC2_16_SR_SAT_BU
:
940 gen_saturate_u(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], 0xff);
942 case OPC2_16_SR_SAT_H
:
943 gen_saturate(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], 0x7fff, -0x8000);
945 case OPC2_16_SR_SAT_HU
:
946 gen_saturate_u(cpu_gpr_d
[r1
], cpu_gpr_d
[r1
], 0xffff);
951 static void decode_16Bit_opc(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
;
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
:
977 case OPC1_16_SRC_MOV
:
978 case OPC1_16_SRC_MOV_A
:
980 case OPC1_16_SRC_SHA
:
981 decode_src_opc(ctx
, op1
);
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
:
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
:
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1050 case OPC1_16_SB_CALL
:
1052 case OPC1_16_SB_JNZ
:
1054 address
= MASK_OP_SB_DISP8_SEXT(ctx
->opcode
);
1055 gen_compute_branch(ctx
, op1
, 0, 0, 0, address
);
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
);
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
);
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
);
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
:
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1143 case OPCM_16_SR_SYSTEM
:
1144 decode_sr_system(env
, ctx
);
1146 case OPCM_16_SR_ACCU
:
1147 decode_sr_accu(env
, ctx
);
1150 r1
= MASK_OP_SR_S1D(ctx
->opcode
);
1151 gen_compute_branch(ctx
, op1
, r1
, 0, 0, 0);
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
]);
1161 * 32 bit instructions
1165 static void decode_abs_ldw(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
));
1179 case OPC2_32_ABS_LD_A
:
1180 tcg_gen_qemu_ld_tl(cpu_gpr_a
[r1
], temp
, ctx
->mem_idx
, MO_LESL
);
1182 case OPC2_32_ABS_LD_D
:
1183 gen_ld_2regs_64(cpu_gpr_d
[r1
+1], cpu_gpr_d
[r1
], temp
, ctx
);
1185 case OPC2_32_ABS_LD_DA
:
1186 gen_ld_2regs_64(cpu_gpr_a
[r1
+1], cpu_gpr_a
[r1
], temp
, ctx
);
1188 case OPC2_32_ABS_LD_W
:
1189 tcg_gen_qemu_ld_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_LESL
);
1193 tcg_temp_free(temp
);
1196 static void decode_abs_ldb(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
));
1210 case OPC2_32_ABS_LD_B
:
1211 tcg_gen_qemu_ld_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_SB
);
1213 case OPC2_32_ABS_LD_BU
:
1214 tcg_gen_qemu_ld_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_UB
);
1216 case OPC2_32_ABS_LD_H
:
1217 tcg_gen_qemu_ld_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_LESW
);
1219 case OPC2_32_ABS_LD_HU
:
1220 tcg_gen_qemu_ld_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_LEUW
);
1224 tcg_temp_free(temp
);
1227 static void decode_abs_ldst_swap(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
));
1241 case OPC2_32_ABS_LDMST
:
1242 gen_ldmst(ctx
, r1
, temp
);
1244 case OPC2_32_ABS_SWAP_W
:
1245 gen_swap(ctx
, r1
, temp
);
1249 tcg_temp_free(temp
);
1252 static void decode_abs_ldst_context(CPUTriCoreState
*env
, DisasContext
*ctx
)
1257 off18
= MASK_OP_ABS_OFF18(ctx
->opcode
);
1258 op2
= MASK_OP_ABS_OP2(ctx
->opcode
);
1261 case OPC2_32_ABS_LDLCX
:
1262 gen_helper_1arg(ldlcx
, EA_ABS_FORMAT(off18
));
1264 case OPC2_32_ABS_LDUCX
:
1265 gen_helper_1arg(lducx
, EA_ABS_FORMAT(off18
));
1267 case OPC2_32_ABS_STLCX
:
1268 gen_helper_1arg(stlcx
, EA_ABS_FORMAT(off18
));
1270 case OPC2_32_ABS_STUCX
:
1271 gen_helper_1arg(stucx
, EA_ABS_FORMAT(off18
));
1276 static void decode_abs_store(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
));
1290 case OPC2_32_ABS_ST_A
:
1291 tcg_gen_qemu_st_tl(cpu_gpr_a
[r1
], temp
, ctx
->mem_idx
, MO_LESL
);
1293 case OPC2_32_ABS_ST_D
:
1294 gen_st_2regs_64(cpu_gpr_d
[r1
+1], cpu_gpr_d
[r1
], temp
, ctx
);
1296 case OPC2_32_ABS_ST_DA
:
1297 gen_st_2regs_64(cpu_gpr_a
[r1
+1], cpu_gpr_a
[r1
], temp
, ctx
);
1299 case OPC2_32_ABS_ST_W
:
1300 tcg_gen_qemu_st_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_LESL
);
1304 tcg_temp_free(temp
);
1307 static void decode_abs_storeb_h(CPUTriCoreState
*env
, DisasContext
*ctx
)
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
));
1321 case OPC2_32_ABS_ST_B
:
1322 tcg_gen_qemu_st_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_UB
);
1324 case OPC2_32_ABS_ST_H
:
1325 tcg_gen_qemu_st_tl(cpu_gpr_d
[r1
], temp
, ctx
->mem_idx
, MO_LEUW
);
1328 tcg_temp_free(temp
);
1331 static void decode_32Bit_opc(CPUTriCoreState
*env
, DisasContext
*ctx
)
1340 op1
= MASK_OP_MAJOR(ctx
->opcode
);
1344 case OPCM_32_ABS_LDW
:
1345 decode_abs_ldw(env
, ctx
);
1347 case OPCM_32_ABS_LDB
:
1348 decode_abs_ldb(env
, ctx
);
1350 case OPCM_32_ABS_LDMST_SWAP
:
1351 decode_abs_ldst_swap(env
, ctx
);
1353 case OPCM_32_ABS_LDST_CONTEXT
:
1354 decode_abs_ldst_context(env
, ctx
);
1356 case OPCM_32_ABS_STORE
:
1357 decode_abs_store(env
, ctx
);
1359 case OPCM_32_ABS_STOREB_H
:
1360 decode_abs_storeb_h(env
, ctx
);
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
);
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
);
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
));
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
);
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 */
1417 ctx
->next_pc
= ctx
->pc
+ 4;
1418 decode_32Bit_opc(env
, ctx
);
1423 gen_intermediate_code_internal(TriCoreCPU
*cpu
, struct TranslationBlock
*tb
,
1426 CPUState
*cs
= CPU(cpu
);
1427 CPUTriCoreState
*env
= &cpu
->env
;
1429 target_ulong pc_start
;
1431 uint16_t *gen_opc_end
;
1434 qemu_log("search pc %d\n", search_pc
);
1439 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
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();
1449 while (ctx
.bstate
== BS_NONE
) {
1450 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
1451 decode_opc(env
, &ctx
, 0);
1455 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
1456 gen_save_pc(ctx
.next_pc
);
1461 gen_save_pc(ctx
.next_pc
);
1465 ctx
.pc
= ctx
.next_pc
;
1468 gen_tb_end(tb
, num_insns
);
1469 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
1471 printf("done_generating search pc\n");
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
);
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);
1490 gen_intermediate_code(CPUTriCoreState
*env
, struct TranslationBlock
*tb
)
1492 gen_intermediate_code_internal(tricore_env_get_cpu(env
), tb
, false);
1496 gen_intermediate_code_pc(CPUTriCoreState
*env
, struct TranslationBlock
*tb
)
1498 gen_intermediate_code_internal(tricore_env_get_cpu(env
), tb
, true);
1502 restore_state_to_opc(CPUTriCoreState
*env
, TranslationBlock
*tb
, int pc_pos
)
1504 env
->PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
1512 void cpu_state_reset(CPUTriCoreState
*env
)
1514 /* Reset Regs to Default Value */
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)
1537 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
1539 for (i
= 0 ; i
< 16 ; i
++) {
1540 cpu_gpr_a
[i
] = tcg_global_mem_new(TCG_AREG0
,
1541 offsetof(CPUTriCoreState
, gpr_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
]),
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
),
1554 cpu_PSW_V
= tcg_global_mem_new(TCG_AREG0
,
1555 offsetof(CPUTriCoreState
, PSW_USB_V
),
1557 cpu_PSW_SV
= tcg_global_mem_new(TCG_AREG0
,
1558 offsetof(CPUTriCoreState
, PSW_USB_SV
),
1560 cpu_PSW_AV
= tcg_global_mem_new(TCG_AREG0
,
1561 offsetof(CPUTriCoreState
, PSW_USB_AV
),
1563 cpu_PSW_SAV
= tcg_global_mem_new(TCG_AREG0
,
1564 offsetof(CPUTriCoreState
, PSW_USB_SAV
),