Loading target-tricore/cpu.h +7 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,13 @@ struct CPUTriCoreState { #define MASK_LCX_LCXS 0x000f0000 #define MASK_LCX_LCX0 0x0000ffff #define MASK_DBGSR_DE 0x1 #define MASK_DBGSR_HALT 0x6 #define MASK_DBGSR_SUSP 0x10 #define MASK_DBGSR_PREVSUSP 0x20 #define MASK_DBGSR_PEVT 0x40 #define MASK_DBGSR_EVTSRC 0x1f00 #define TRICORE_HFLAG_KUU 0x3 #define TRICORE_HFLAG_UM0 0x00002 /* user mode-0 flag */ #define TRICORE_HFLAG_UM1 0x00001 /* user mode-1 flag */ Loading target-tricore/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -122,10 +122,13 @@ DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) DEF_HELPER_2(bisr, void, env, i32) DEF_HELPER_1(rfe, void, env) DEF_HELPER_1(rfm, void, env) DEF_HELPER_2(ldlcx, void, env, i32) DEF_HELPER_2(lducx, void, env, i32) DEF_HELPER_2(stlcx, void, env, i32) DEF_HELPER_2(stucx, void, env, i32) DEF_HELPER_1(svlcx, void, env) DEF_HELPER_1(rslcx, void, env) /* Address mode helper */ DEF_HELPER_1(br_update, i32, i32) DEF_HELPER_2(circ_update, i32, i32, i32) Loading target-tricore/op_helper.c +89 −0 Original line number Diff line number Diff line Loading @@ -2499,6 +2499,26 @@ void helper_rfe(CPUTriCoreState *env) psw_write(env, new_PSW); } void helper_rfm(CPUTriCoreState *env) { env->PC = (env->gpr_a[11] & ~0x1); /* ICR.IE = PCXI.PIE; */ env->ICR = (env->ICR & ~MASK_ICR_IE) | ((env->PCXI & ~MASK_PCXI_PIE) >> 15); /* ICR.CCPN = PCXI.PCPN; */ env->ICR = (env->ICR & ~MASK_ICR_CCPN) | ((env->PCXI & ~MASK_PCXI_PCPN) >> 24); /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ env->PCXI = cpu_ldl_data(env, env->DCX); psw_write(env, cpu_ldl_data(env, env->DCX+4)); env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); if (tricore_feature(env, TRICORE_FEATURE_131)) { env->DBGTCR = 0; } } void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) { uint32_t dummy; Loading @@ -2523,6 +2543,75 @@ void helper_stucx(CPUTriCoreState *env, uint32_t ea) save_context_upper(env, ea); } void helper_svlcx(CPUTriCoreState *env) { target_ulong tmp_FCX; target_ulong ea; target_ulong new_FCX; if (env->FCX == 0) { /* FCU trap */ } /* tmp_FCX = FCX; */ tmp_FCX = env->FCX; /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ ea = ((env->FCX & MASK_FCX_FCXS) << 12) + ((env->FCX & MASK_FCX_FCXO) << 6); /* new_FCX = M(EA, word); */ new_FCX = cpu_ldl_data(env, ea); /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15]}; */ save_context_lower(env, ea); /* PCXI.PCPN = ICR.CCPN; */ env->PCXI = (env->PCXI & 0xffffff) + ((env->ICR & MASK_ICR_CCPN) << 24); /* PCXI.PIE = ICR.IE; */ env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + ((env->ICR & MASK_ICR_IE) << 15)); /* PCXI.UL = 0; */ env->PCXI &= ~MASK_PCXI_UL; /* PCXI[19: 0] = FCX[19: 0]; */ env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); /* FCX[19: 0] = new_FCX[19: 0]; */ env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); /* if (tmp_FCX == LCX) trap(FCD);*/ if (tmp_FCX == env->LCX) { /* FCD trap */ } } void helper_rslcx(CPUTriCoreState *env) { target_ulong ea; target_ulong new_PCXI; /* if (PCXI[19: 0] == 0) then trap(CSU); */ if ((env->PCXI & 0xfffff) == 0) { /* CSU trap */ } /* if (PCXI.UL == 1) then trap(CTYP); */ if ((env->PCXI & MASK_PCXI_UL) == 1) { /* CTYP trap */ } /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + ((env->PCXI & MASK_PCXI_PCXO) << 6); /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ restore_context_upper(env, ea, &new_PCXI, &env->gpr_a[11]); /* M(EA, word) = FCX; */ cpu_stl_data(env, ea, env->FCX); /* M(EA, word) = FCX; */ cpu_stl_data(env, ea, env->FCX); /* FCX[19: 0] = PCXI[19: 0]; */ env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); /* PCXI = new_PCXI; */ env->PCXI = new_PCXI; } void helper_psw_write(CPUTriCoreState *env, uint32_t arg) { psw_write(env, arg); Loading target-tricore/translate.c +76 −0 Original line number Diff line number Diff line Loading @@ -3326,6 +3326,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe); tcg_gen_exit_tb(0); break; case OPC2_32_SYS_RET: case OPC2_16_SR_RET: gen_helper_ret(cpu_env); tcg_gen_exit_tb(0); Loading Loading @@ -7695,6 +7696,71 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } /* SYS Format*/ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) { uint32_t op2; TCGLabel *l1; TCGv tmp; op2 = MASK_OP_SYS_OP2(ctx->opcode); switch (op2) { case OPC2_32_SYS_DEBUG: /* raise EXCP_DEBUG */ break; case OPC2_32_SYS_DISABLE: tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~MASK_ICR_IE); break; case OPC2_32_SYS_DSYNC: break; case OPC2_32_SYS_ENABLE: tcg_gen_ori_tl(cpu_ICR, cpu_ICR, MASK_ICR_IE); break; case OPC2_32_SYS_ISYNC: break; case OPC2_32_SYS_NOP: break; case OPC2_32_SYS_RET: gen_compute_branch(ctx, op2, 0, 0, 0, 0); break; case OPC2_32_SYS_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(0); ctx->bstate = BS_BRANCH; break; case OPC2_32_SYS_RFM: if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { tmp = tcg_temp_new(); l1 = gen_new_label(); tcg_gen_ld32u_tl(tmp, cpu_env, offsetof(CPUTriCoreState, DBGSR)); tcg_gen_andi_tl(tmp, tmp, MASK_DBGSR_DE); tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1); gen_helper_rfm(cpu_env); gen_set_label(l1); tcg_gen_exit_tb(0); ctx->bstate = BS_BRANCH; tcg_temp_free(tmp); } else { /* generate privilege trap */ } break; case OPC2_32_SYS_RSLCX: gen_helper_rslcx(cpu_env); break; case OPC2_32_SYS_SVLCX: gen_helper_svlcx(cpu_env); break; case OPC2_32_SYS_TRAPSV: /* TODO: raise sticky overflow trap */ break; case OPC2_32_SYS_TRAPV: /* TODO: raise overflow trap */ break; } } static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) { int op1; Loading Loading @@ -8017,6 +8083,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPCM_32_RRRW_EXTRACT_INSERT: decode_rrrw_extract_insert(env, ctx); break; /* SYS format */ case OPCM_32_SYS_INTERRUPTS: decode_sys_interrupts(env, ctx); break; case OPC1_32_SYS_RSTV: tcg_gen_movi_tl(cpu_PSW_V, 0); tcg_gen_mov_tl(cpu_PSW_SV, cpu_PSW_V); tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V); tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V); break; } } Loading Loading
target-tricore/cpu.h +7 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,13 @@ struct CPUTriCoreState { #define MASK_LCX_LCXS 0x000f0000 #define MASK_LCX_LCX0 0x0000ffff #define MASK_DBGSR_DE 0x1 #define MASK_DBGSR_HALT 0x6 #define MASK_DBGSR_SUSP 0x10 #define MASK_DBGSR_PREVSUSP 0x20 #define MASK_DBGSR_PEVT 0x40 #define MASK_DBGSR_EVTSRC 0x1f00 #define TRICORE_HFLAG_KUU 0x3 #define TRICORE_HFLAG_UM0 0x00002 /* user mode-0 flag */ #define TRICORE_HFLAG_UM1 0x00001 /* user mode-1 flag */ Loading
target-tricore/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -122,10 +122,13 @@ DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) DEF_HELPER_2(bisr, void, env, i32) DEF_HELPER_1(rfe, void, env) DEF_HELPER_1(rfm, void, env) DEF_HELPER_2(ldlcx, void, env, i32) DEF_HELPER_2(lducx, void, env, i32) DEF_HELPER_2(stlcx, void, env, i32) DEF_HELPER_2(stucx, void, env, i32) DEF_HELPER_1(svlcx, void, env) DEF_HELPER_1(rslcx, void, env) /* Address mode helper */ DEF_HELPER_1(br_update, i32, i32) DEF_HELPER_2(circ_update, i32, i32, i32) Loading
target-tricore/op_helper.c +89 −0 Original line number Diff line number Diff line Loading @@ -2499,6 +2499,26 @@ void helper_rfe(CPUTriCoreState *env) psw_write(env, new_PSW); } void helper_rfm(CPUTriCoreState *env) { env->PC = (env->gpr_a[11] & ~0x1); /* ICR.IE = PCXI.PIE; */ env->ICR = (env->ICR & ~MASK_ICR_IE) | ((env->PCXI & ~MASK_PCXI_PIE) >> 15); /* ICR.CCPN = PCXI.PCPN; */ env->ICR = (env->ICR & ~MASK_ICR_CCPN) | ((env->PCXI & ~MASK_PCXI_PCPN) >> 24); /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ env->PCXI = cpu_ldl_data(env, env->DCX); psw_write(env, cpu_ldl_data(env, env->DCX+4)); env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); if (tricore_feature(env, TRICORE_FEATURE_131)) { env->DBGTCR = 0; } } void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) { uint32_t dummy; Loading @@ -2523,6 +2543,75 @@ void helper_stucx(CPUTriCoreState *env, uint32_t ea) save_context_upper(env, ea); } void helper_svlcx(CPUTriCoreState *env) { target_ulong tmp_FCX; target_ulong ea; target_ulong new_FCX; if (env->FCX == 0) { /* FCU trap */ } /* tmp_FCX = FCX; */ tmp_FCX = env->FCX; /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ ea = ((env->FCX & MASK_FCX_FCXS) << 12) + ((env->FCX & MASK_FCX_FCXO) << 6); /* new_FCX = M(EA, word); */ new_FCX = cpu_ldl_data(env, ea); /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15]}; */ save_context_lower(env, ea); /* PCXI.PCPN = ICR.CCPN; */ env->PCXI = (env->PCXI & 0xffffff) + ((env->ICR & MASK_ICR_CCPN) << 24); /* PCXI.PIE = ICR.IE; */ env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + ((env->ICR & MASK_ICR_IE) << 15)); /* PCXI.UL = 0; */ env->PCXI &= ~MASK_PCXI_UL; /* PCXI[19: 0] = FCX[19: 0]; */ env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); /* FCX[19: 0] = new_FCX[19: 0]; */ env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); /* if (tmp_FCX == LCX) trap(FCD);*/ if (tmp_FCX == env->LCX) { /* FCD trap */ } } void helper_rslcx(CPUTriCoreState *env) { target_ulong ea; target_ulong new_PCXI; /* if (PCXI[19: 0] == 0) then trap(CSU); */ if ((env->PCXI & 0xfffff) == 0) { /* CSU trap */ } /* if (PCXI.UL == 1) then trap(CTYP); */ if ((env->PCXI & MASK_PCXI_UL) == 1) { /* CTYP trap */ } /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + ((env->PCXI & MASK_PCXI_PCXO) << 6); /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ restore_context_upper(env, ea, &new_PCXI, &env->gpr_a[11]); /* M(EA, word) = FCX; */ cpu_stl_data(env, ea, env->FCX); /* M(EA, word) = FCX; */ cpu_stl_data(env, ea, env->FCX); /* FCX[19: 0] = PCXI[19: 0]; */ env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); /* PCXI = new_PCXI; */ env->PCXI = new_PCXI; } void helper_psw_write(CPUTriCoreState *env, uint32_t arg) { psw_write(env, arg); Loading
target-tricore/translate.c +76 −0 Original line number Diff line number Diff line Loading @@ -3326,6 +3326,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe); tcg_gen_exit_tb(0); break; case OPC2_32_SYS_RET: case OPC2_16_SR_RET: gen_helper_ret(cpu_env); tcg_gen_exit_tb(0); Loading Loading @@ -7695,6 +7696,71 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } /* SYS Format*/ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx) { uint32_t op2; TCGLabel *l1; TCGv tmp; op2 = MASK_OP_SYS_OP2(ctx->opcode); switch (op2) { case OPC2_32_SYS_DEBUG: /* raise EXCP_DEBUG */ break; case OPC2_32_SYS_DISABLE: tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~MASK_ICR_IE); break; case OPC2_32_SYS_DSYNC: break; case OPC2_32_SYS_ENABLE: tcg_gen_ori_tl(cpu_ICR, cpu_ICR, MASK_ICR_IE); break; case OPC2_32_SYS_ISYNC: break; case OPC2_32_SYS_NOP: break; case OPC2_32_SYS_RET: gen_compute_branch(ctx, op2, 0, 0, 0, 0); break; case OPC2_32_SYS_RFE: gen_helper_rfe(cpu_env); tcg_gen_exit_tb(0); ctx->bstate = BS_BRANCH; break; case OPC2_32_SYS_RFM: if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { tmp = tcg_temp_new(); l1 = gen_new_label(); tcg_gen_ld32u_tl(tmp, cpu_env, offsetof(CPUTriCoreState, DBGSR)); tcg_gen_andi_tl(tmp, tmp, MASK_DBGSR_DE); tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1); gen_helper_rfm(cpu_env); gen_set_label(l1); tcg_gen_exit_tb(0); ctx->bstate = BS_BRANCH; tcg_temp_free(tmp); } else { /* generate privilege trap */ } break; case OPC2_32_SYS_RSLCX: gen_helper_rslcx(cpu_env); break; case OPC2_32_SYS_SVLCX: gen_helper_svlcx(cpu_env); break; case OPC2_32_SYS_TRAPSV: /* TODO: raise sticky overflow trap */ break; case OPC2_32_SYS_TRAPV: /* TODO: raise overflow trap */ break; } } static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) { int op1; Loading Loading @@ -8017,6 +8083,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) case OPCM_32_RRRW_EXTRACT_INSERT: decode_rrrw_extract_insert(env, ctx); break; /* SYS format */ case OPCM_32_SYS_INTERRUPTS: decode_sys_interrupts(env, ctx); break; case OPC1_32_SYS_RSTV: tcg_gen_movi_tl(cpu_PSW_V, 0); tcg_gen_mov_tl(cpu_PSW_SV, cpu_PSW_V); tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V); tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V); break; } } Loading