#include "exec/translator.h"
#include "exec/log.h"
+#define HELPER_H "helper.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
+
+#define DISAS_EXIT DISAS_TARGET_0
+#define DISAS_EXIT_UPDATE DISAS_TARGET_1
+#define DISAS_JUMP DISAS_TARGET_2
+
/*
* TCG registers
*/
static TCGv cpu_PSW_AV;
static TCGv cpu_PSW_SAV;
-#include "exec/gen-icount.h"
-
static const char *regnames_a[] = {
"a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
"a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
uint32_t opcode;
/* Routine used to access memory */
int mem_idx;
- uint32_t hflags, saved_hflags;
+ int priv;
uint64_t features;
+ uint32_t icr_ie_mask, icr_ie_offset;
} DisasContext;
static int has_feature(DisasContext *ctx, int feature)
* Functions to generate micro-ops
*/
-/* Makros for generating helpers */
+/* Macros for generating helpers */
#define gen_helper_1arg(name, arg) do { \
TCGv_i32 helper_tmp = tcg_constant_i32(arg); \
{
TCGv temp = tcg_temp_new();
TCGv temp2 = tcg_temp_new();
+ CHECK_REG_PAIR(reg);
tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp,
cpu_gpr_d[reg], temp);
TCGv temp = tcg_temp_new();
TCGv temp2 = tcg_temp_new();
TCGv temp3 = tcg_temp_new();
-
+ CHECK_REG_PAIR(reg);
tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]);
tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]);
tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
}
-
/* We generate loads and store to core special function register (csfr) through
the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
- makros R, A and E, which allow read-only, all and endinit protected access.
- These makros also specify in which ISA version the csfr was introduced. */
+ macros R, A and E, which allow read-only, all and endinit protected access.
+ These macros also specify in which ISA version the csfr was introduced. */
#define R(ADDRESS, REG, FEATURE) \
case ADDRESS: \
if (has_feature(ctx, FEATURE)) { \
#undef E
#define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
- since no execption occurs */
+ since no exception occurs */
#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
case ADDRESS: \
if (has_feature(ctx, FEATURE)) { \
static inline void gen_mtcr(DisasContext *ctx, TCGv r1,
int32_t offset)
{
- if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
+ if (ctx->priv == TRICORE_PRIV_SM) {
/* since we're caching PSW make this a special case */
if (offset == 0xfe04) {
gen_helper_psw_write(cpu_env, r1);
+ ctx->base.is_jmp = DISAS_EXIT_UPDATE;
} else {
switch (offset) {
#include "csfr.h.inc"
}
}
} else {
- /* generate privilege trap */
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
}
}
static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
{
- TCGv sat_neg = tcg_const_i32(low);
- TCGv temp = tcg_const_i32(up);
-
- /* sat_neg = (arg < low ) ? low : arg; */
- tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
-
- /* ret = (sat_neg > up ) ? up : sat_neg; */
- tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+ tcg_gen_smax_tl(ret, arg, tcg_constant_i32(low));
+ tcg_gen_smin_tl(ret, ret, tcg_constant_i32(up));
}
static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
{
- TCGv temp = tcg_const_i32(up);
- /* sat_neg = (arg > up ) ? up : arg; */
- tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+ tcg_gen_umin_tl(ret, arg, tcg_constant_i32(up));
}
static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
gen_accumulating_cond(cond, ret, r1, temp, op);
}
-/* ret = (r1 cond r2) ? 0xFFFFFFFF ? 0x00000000;*/
-static inline void gen_cond_w(TCGCond cond, TCGv ret, TCGv r1, TCGv r2)
-{
- tcg_gen_setcond_tl(cond, ret, r1, r2);
- tcg_gen_neg_tl(ret, ret);
-}
-
static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
{
TCGv b0 = tcg_temp_new();
gen_save_pc(dest);
tcg_gen_lookup_and_goto_ptr();
}
+ ctx->base.is_jmp = DISAS_NORETURN;
}
static void generate_trap(DisasContext *ctx, int class, int tin)
tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
tcg_gen_mov_tl(cpu_PC, temp);
- tcg_gen_exit_tb(NULL, 0);
- ctx->base.is_jmp = DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_EXIT;
}
static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
/* SR-format jumps */
case OPC1_16_SR_JI:
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
- tcg_gen_exit_tb(NULL, 0);
+ ctx->base.is_jmp = DISAS_EXIT;
break;
case OPC2_32_SYS_RET:
case OPC2_16_SR_RET:
gen_helper_ret(cpu_env);
- tcg_gen_exit_tb(NULL, 0);
+ ctx->base.is_jmp = DISAS_EXIT;
break;
/* B-format */
case OPC1_32_B_CALLA:
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
- ctx->base.is_jmp = DISAS_NORETURN;
}
break;
case OPC1_16_SRC_MOV_E:
if (has_feature(ctx, TRICORE_FEATURE_16)) {
+ CHECK_REG_PAIR(r1);
tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
} else {
tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
break;
case OPC1_16_SC_BISR:
- gen_helper_1arg(bisr, const16 & 0xff);
+ if (ctx->priv == TRICORE_PRIV_SM) {
+ gen_helper_1arg(bisr, const16 & 0xff);
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
break;
case OPC1_16_SC_LD_A:
gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
break;
case OPC2_16_SR_RFE:
gen_helper_rfe(cpu_env);
- tcg_gen_exit_tb(NULL, 0);
- ctx->base.is_jmp = DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_EXIT;
break;
case OPC2_16_SR_DEBUG:
/* raise EXCP_DEBUG */
const9 = MASK_OP_RC_CONST9(ctx->opcode);
op2 = MASK_OP_RC_OP2(ctx->opcode);
- temp = tcg_temp_new();
-
switch (op2) {
case OPC2_32_RC_AND:
tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
tcg_gen_andi_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], ~const9);
break;
case OPC2_32_RC_NAND:
+ temp = tcg_temp_new();
tcg_gen_movi_tl(temp, const9);
tcg_gen_nand_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
break;
case OPC2_32_RC_NOR:
+ temp = tcg_temp_new();
tcg_gen_movi_tl(temp, const9);
tcg_gen_nor_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
break;
case OPC2_32_RC_XOR:
tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
break;
+ case OPC2_32_RC_SHUFFLE:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ temp = tcg_constant_i32(const9);
+ gen_helper_shuffle(cpu_gpr_d[r2], cpu_gpr_d[r1], temp);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
switch (op2) {
case OPC2_32_RC_BISR:
- gen_helper_1arg(bisr, const9);
+ if (ctx->priv == TRICORE_PRIV_SM) {
+ gen_helper_1arg(bisr, const9);
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
break;
case OPC2_32_RC_SYSCALL:
- /* TODO: Add exception generation */
+ generate_trap(ctx, TRAPC_SYSCALL, const9 & 0xff);
break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
case OPC2_32_RCPW_INSERT:
+ /* tcg_gen_deposit_tl() does not handle the case of width = 0 */
+ if (width == 0) {
+ tcg_gen_mov_tl(cpu_gpr_d[r2], cpu_gpr_d[r1]);
/* if pos + width > 32 undefined result */
- if (pos + width <= 32) {
+ } else if (pos + width <= 32) {
temp = tcg_constant_i32(const4);
tcg_gen_deposit_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, pos, width);
}
switch (op2) {
case OPC2_32_RCRW_IMASK:
+ CHECK_REG_PAIR(r4);
tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
tcg_gen_movi_tl(temp2, (1 << width) - 1);
tcg_gen_shl_tl(cpu_gpr_d[r4 + 1], temp2, temp);
gen_helper_eq_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_EQ_W:
- gen_cond_w(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ tcg_gen_negsetcond_tl(TCG_COND_EQ, cpu_gpr_d[r3],
+ cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_EQANY_B:
gen_helper_eqany_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
gen_helper_lt_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_LT_W:
- gen_cond_w(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ tcg_gen_negsetcond_tl(TCG_COND_LT, cpu_gpr_d[r3],
+ cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_LT_WU:
- gen_cond_w(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ tcg_gen_negsetcond_tl(TCG_COND_LTU, cpu_gpr_d[r3],
+ cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_MAX:
tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r3], cpu_gpr_d[r1],
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
break;
case OPC2_32_RR_JLI:
- tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
+ tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
break;
case OPC2_32_RR_CALLI:
gen_helper_1arg(call, ctx->pc_succ_insn);
break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ return;
}
- tcg_gen_exit_tb(NULL, 0);
- ctx->base.is_jmp = DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_JUMP;
}
static void decode_rr_divide(DisasContext *ctx)
tcg_gen_sari_tl(cpu_gpr_d[r3+1], cpu_gpr_d[r1], 31);
break;
case OPC2_32_RR_DVINIT_U:
+ CHECK_REG_PAIR(r3);
/* overflow = (D[b] == 0) */
tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
CHECK_REG_PAIR(r3);
gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
- case OPC2_32_RR_CRC32:
+ case OPC2_32_RR_CRC32_B:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ gen_helper_crc32b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
+ case OPC2_32_RR_CRC32: /* CRC32B.W in 1.6.2 */
if (has_feature(ctx, TRICORE_FEATURE_161)) {
- gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ gen_helper_crc32_be(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
+ case OPC2_32_RR_CRC32L_W:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ gen_helper_crc32_le(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
+
+ case OPC2_32_RR_POPCNT_W:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ tcg_gen_ctpop_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
} else {
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
case OPC2_32_RR_DIV:
if (has_feature(ctx, TRICORE_FEATURE_16)) {
+ CHECK_REG_PAIR(r3);
GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
} else {
break;
case OPC2_32_RR_DIV_U:
if (has_feature(ctx, TRICORE_FEATURE_16)) {
+ CHECK_REG_PAIR(r3);
GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2]);
} else {
case OPC2_32_RR_DIV_F:
gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ case OPC2_32_RR_FTOHP:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ gen_helper_ftohp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
+ case OPC2_32_RR_HPTOF:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ gen_helper_hptof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
case OPC2_32_RR_CMP_F:
gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_ITOF:
gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
break;
+ case OPC2_32_RR_FTOU:
+ gen_helper_ftou(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
case OPC2_32_RR_FTOUZ:
- gen_helper_ftouz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ if (has_feature(ctx, TRICORE_FEATURE_131)) {
+ gen_helper_ftouz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_RR_UPDFL:
gen_helper_updfl(cpu_env, cpu_gpr_d[r1]);
break;
case OPC2_32_RRPW_INSERT:
- if (pos + width <= 32) {
+ /* tcg_gen_deposit_tl() does not handle the case of width = 0 */
+ if (width == 0) {
+ tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+ } else if (pos + width <= 32) {
tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos, width);
}
gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
+ case OPC2_32_RRR_CRCN:
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ gen_helper_crcn(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2],
+ cpu_gpr_d[r3]);
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
+ break;
case OPC2_32_RRR_ADD_F:
gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]);
break;
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MSUB_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
break;
case OPC2_32_RRRW_IMASK:
temp2 = tcg_temp_new();
-
+ CHECK_REG_PAIR(r4);
tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f);
tcg_gen_movi_tl(temp2, (1 << width) - 1);
tcg_gen_shl_tl(temp2, temp2, temp);
/* raise EXCP_DEBUG */
break;
case OPC2_32_SYS_DISABLE:
- tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~MASK_ICR_IE_1_3);
+ if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
+ tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask);
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
break;
+ case OPC2_32_SYS_DISABLE_D:
+ if (has_feature(ctx, TRICORE_FEATURE_16)) {
+ if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
+ tcg_gen_extract_tl(cpu_gpr_d[r1], cpu_ICR,
+ ctx->icr_ie_offset, 1);
+ tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask);
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
case OPC2_32_SYS_DSYNC:
break;
case OPC2_32_SYS_ENABLE:
- tcg_gen_ori_tl(cpu_ICR, cpu_ICR, MASK_ICR_IE_1_3);
+ if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
+ tcg_gen_ori_tl(cpu_ICR, cpu_ICR, ctx->icr_ie_mask);
+ ctx->base.is_jmp = DISAS_EXIT_UPDATE;
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
break;
case OPC2_32_SYS_ISYNC:
break;
break;
case OPC2_32_SYS_RFE:
gen_helper_rfe(cpu_env);
- tcg_gen_exit_tb(NULL, 0);
- ctx->base.is_jmp = DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_EXIT;
break;
case OPC2_32_SYS_RFM:
- if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
+ if (ctx->priv == TRICORE_PRIV_SM) {
tmp = tcg_temp_new();
l1 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1);
gen_helper_rfm(cpu_env);
gen_set_label(l1);
- tcg_gen_exit_tb(NULL, 0);
- ctx->base.is_jmp = DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_EXIT;
} else {
- /* generate privilege trap */
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
}
break;
case OPC2_32_SYS_RSLCX:
break;
case OPC2_32_SYS_RESTORE:
if (has_feature(ctx, TRICORE_FEATURE_16)) {
- if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM ||
- (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
- tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
- } /* else raise privilege trap */
+ if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
+ tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1],
+ ctx->icr_ie_offset, 1);
+ ctx->base.is_jmp = DISAS_EXIT_UPDATE;
+ } else {
+ generate_trap(ctx, TRAPC_PROT, TIN1_PRIV);
+ }
} else {
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
static void decode_32Bit_opc(DisasContext *ctx)
{
- int op1;
+ int op1, op2;
int32_t r1, r2, r3;
int32_t address, const16;
int8_t b, const4;
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16);
break;
- case OPC1_32_ABS_LEA:
+ case OPCM_32_ABS_LEA_LHA:
address = MASK_OP_ABS_OFF18(ctx->opcode);
r1 = MASK_OP_ABS_S1D(ctx->opcode);
+
+ if (has_feature(ctx, TRICORE_FEATURE_162)) {
+ op2 = MASK_OP_ABS_OP2(ctx->opcode);
+ if (op2 == OPC2_32_ABS_LHA) {
+ tcg_gen_movi_tl(cpu_gpr_a[r1], address << 14);
+ break;
+ }
+ /* otherwise translate regular LEA */
+ }
+
tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address));
break;
/* ABSB-format */
temp2 = tcg_temp_new(); /* width*/
temp3 = tcg_temp_new(); /* pos */
- CHECK_REG_PAIR(r3);
+ CHECK_REG_PAIR(r2);
- tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
- tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
+ tcg_gen_andi_tl(temp2, cpu_gpr_d[r2 + 1], 0x1f);
+ tcg_gen_andi_tl(temp3, cpu_gpr_d[r2], 0x1f);
- gen_insert(cpu_gpr_d[r2], cpu_gpr_d[r1], temp, temp2, temp3);
+ gen_insert(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, temp2, temp3);
break;
/* RCRW Format */
case OPCM_32_RCRW_MASK_INSERT:
DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPUTriCoreState *env = cs->env_ptr;
ctx->mem_idx = cpu_mmu_index(env, false);
- ctx->hflags = (uint32_t)ctx->base.tb->flags;
+
+ uint32_t tb_flags = (uint32_t)ctx->base.tb->flags;
+ ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
+
ctx->features = env->features;
+ if (has_feature(ctx, TRICORE_FEATURE_161)) {
+ ctx->icr_ie_mask = R_ICR_IE_161_MASK;
+ ctx->icr_ie_offset = R_ICR_IE_161_SHIFT;
+ } else {
+ ctx->icr_ie_mask = R_ICR_IE_13_MASK;
+ ctx->icr_ie_offset = R_ICR_IE_13_SHIFT;
+ }
}
static void tricore_tr_tb_start(DisasContextBase *db, CPUState *cpu)
* 4 bytes from the page boundary, so we cross the page if the first
* 16 bits indicate that this is a 32 bit insn.
*/
- uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next);
+ uint16_t insn = translator_lduw(env, &ctx->base, ctx->base.pc_next);
return !tricore_insn_is_16bit(insn);
}
uint16_t insn_lo;
bool is_16bit;
- insn_lo = cpu_lduw_code(env, ctx->base.pc_next);
+ insn_lo = translator_lduw(env, &ctx->base, ctx->base.pc_next);
is_16bit = tricore_insn_is_16bit(insn_lo);
if (is_16bit) {
ctx->opcode = insn_lo;
ctx->pc_succ_insn = ctx->base.pc_next + 2;
decode_16Bit_opc(ctx);
} else {
- uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ uint32_t insn_hi = translator_lduw(env, &ctx->base,
+ ctx->base.pc_next + 2);
ctx->opcode = insn_hi << 16 | insn_lo;
ctx->pc_succ_insn = ctx->base.pc_next + 4;
decode_32Bit_opc(ctx);
case DISAS_TOO_MANY:
gen_goto_tb(ctx, 0, ctx->base.pc_next);
break;
+ case DISAS_EXIT_UPDATE:
+ gen_save_pc(ctx->base.pc_next);
+ /* fall through */
+ case DISAS_EXIT:
+ tcg_gen_exit_tb(NULL, 0);
+ break;
+ case DISAS_JUMP:
+ tcg_gen_lookup_and_goto_ptr();
+ break;
case DISAS_NORETURN:
break;
default: