From b724b012a4ea9877c5ddad254df63735a945618c Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 25 Feb 2015 12:29:24 +0000 Subject: target-tricore: Add instructions of SYS opcode format This adds only the non trap instructions. Signed-off-by: Bastian Koppelmann --- target-tricore/cpu.h | 7 ++++ target-tricore/helper.h | 3 ++ target-tricore/op_helper.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ target-tricore/translate.c | 76 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+) (limited to 'target-tricore') diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h index b473426ce0..90bf0069b5 100644 --- a/target-tricore/cpu.h +++ b/target-tricore/cpu.h @@ -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 */ diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 8186d3603c..1a49b00ccb 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -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) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 76d7911235..97b0c8b8d3 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -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; @@ -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); diff --git a/target-tricore/translate.c b/target-tricore/translate.c index f03cd26278..15a24f7c98 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -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); @@ -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; @@ -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; } } -- cgit v1.2.3