mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
target-tricore: Add instructions of SYS opcode format
This adds only the non trap instructions. Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
This commit is contained in:
parent
eb989d2545
commit
b724b012a4
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user