target-tricore: Add instructions of RLC opcode format
Add instructions of RLC opcode format. Add helper psw_write/read. Add microcode generator gen_mtcr/mfcr, which loads/stores a value to a core special function register, which are defined in csfr.def Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
ed51626066
commit
2b2f7d97d8
124
target-tricore/csfr.def
Normal file
124
target-tricore/csfr.def
Normal file
@ -0,0 +1,124 @@
|
||||
/* A(ll) access permited
|
||||
R(ead only) access
|
||||
E(nd init protected) access
|
||||
|
||||
A|R|E(offset, register, feature introducing reg)
|
||||
|
||||
NOTE: PSW is handled as a special case in gen_mtcr/mfcr */
|
||||
|
||||
A(0xfe00, PCXI, TRICORE_FEATURE_13)
|
||||
A(0xfe08, PC, TRICORE_FEATURE_13)
|
||||
A(0xfe14, SYSCON, TRICORE_FEATURE_13)
|
||||
R(0xfe18, CPU_ID, TRICORE_FEATURE_13)
|
||||
E(0xfe20, BIV, TRICORE_FEATURE_13)
|
||||
E(0xfe24, BTV, TRICORE_FEATURE_13)
|
||||
E(0xfe28, ISP, TRICORE_FEATURE_13)
|
||||
A(0xfe2c, ICR, TRICORE_FEATURE_13)
|
||||
A(0xfe38, FCX, TRICORE_FEATURE_13)
|
||||
A(0xfe3c, LCX, TRICORE_FEATURE_13)
|
||||
E(0x9400, COMPAT, TRICORE_FEATURE_131)
|
||||
/* memory protection register */
|
||||
A(0xC000, DPR0_0L, TRICORE_FEATURE_13)
|
||||
A(0xC004, DPR0_0U, TRICORE_FEATURE_13)
|
||||
A(0xC008, DPR0_1L, TRICORE_FEATURE_13)
|
||||
A(0xC00C, DPR0_1U, TRICORE_FEATURE_13)
|
||||
A(0xC010, DPR0_2L, TRICORE_FEATURE_13)
|
||||
A(0xC014, DPR0_2U, TRICORE_FEATURE_13)
|
||||
A(0xC018, DPR0_3L, TRICORE_FEATURE_13)
|
||||
A(0xC01C, DPR0_3U, TRICORE_FEATURE_13)
|
||||
A(0xC400, DPR1_0L, TRICORE_FEATURE_13)
|
||||
A(0xC404, DPR1_0U, TRICORE_FEATURE_13)
|
||||
A(0xC408, DPR1_1L, TRICORE_FEATURE_13)
|
||||
A(0xC40C, DPR1_1U, TRICORE_FEATURE_13)
|
||||
A(0xC410, DPR1_2L, TRICORE_FEATURE_13)
|
||||
A(0xC414, DPR1_2U, TRICORE_FEATURE_13)
|
||||
A(0xC418, DPR1_3L, TRICORE_FEATURE_13)
|
||||
A(0xC41C, DPR1_3U, TRICORE_FEATURE_13)
|
||||
A(0xC800, DPR2_0L, TRICORE_FEATURE_13)
|
||||
A(0xC804, DPR2_0U, TRICORE_FEATURE_13)
|
||||
A(0xC808, DPR2_1L, TRICORE_FEATURE_13)
|
||||
A(0xC80C, DPR2_1U, TRICORE_FEATURE_13)
|
||||
A(0xC810, DPR2_2L, TRICORE_FEATURE_13)
|
||||
A(0xC814, DPR2_2U, TRICORE_FEATURE_13)
|
||||
A(0xC818, DPR2_3L, TRICORE_FEATURE_13)
|
||||
A(0xC81C, DPR2_3U, TRICORE_FEATURE_13)
|
||||
A(0xCC00, DPR3_0L, TRICORE_FEATURE_13)
|
||||
A(0xCC04, DPR3_0U, TRICORE_FEATURE_13)
|
||||
A(0xCC08, DPR3_1L, TRICORE_FEATURE_13)
|
||||
A(0xCC0C, DPR3_1U, TRICORE_FEATURE_13)
|
||||
A(0xCC10, DPR3_2L, TRICORE_FEATURE_13)
|
||||
A(0xCC14, DPR3_2U, TRICORE_FEATURE_13)
|
||||
A(0xCC18, DPR3_3L, TRICORE_FEATURE_13)
|
||||
A(0xCC1C, DPR3_3U, TRICORE_FEATURE_13)
|
||||
A(0xD000, CPR0_0L, TRICORE_FEATURE_13)
|
||||
A(0xD004, CPR0_0U, TRICORE_FEATURE_13)
|
||||
A(0xD008, CPR0_1L, TRICORE_FEATURE_13)
|
||||
A(0xD00C, CPR0_1U, TRICORE_FEATURE_13)
|
||||
A(0xD010, CPR0_2L, TRICORE_FEATURE_13)
|
||||
A(0xD014, CPR0_2U, TRICORE_FEATURE_13)
|
||||
A(0xD018, CPR0_3L, TRICORE_FEATURE_13)
|
||||
A(0xD01C, CPR0_3U, TRICORE_FEATURE_13)
|
||||
A(0xD400, CPR1_0L, TRICORE_FEATURE_13)
|
||||
A(0xD404, CPR1_0U, TRICORE_FEATURE_13)
|
||||
A(0xD408, CPR1_1L, TRICORE_FEATURE_13)
|
||||
A(0xD40C, CPR1_1U, TRICORE_FEATURE_13)
|
||||
A(0xD410, CPR1_2L, TRICORE_FEATURE_13)
|
||||
A(0xD414, CPR1_2U, TRICORE_FEATURE_13)
|
||||
A(0xD418, CPR1_3L, TRICORE_FEATURE_13)
|
||||
A(0xD41C, CPR1_3U, TRICORE_FEATURE_13)
|
||||
A(0xD800, CPR2_0L, TRICORE_FEATURE_13)
|
||||
A(0xD804, CPR2_0U, TRICORE_FEATURE_13)
|
||||
A(0xD808, CPR2_1L, TRICORE_FEATURE_13)
|
||||
A(0xD80C, CPR2_1U, TRICORE_FEATURE_13)
|
||||
A(0xD810, CPR2_2L, TRICORE_FEATURE_13)
|
||||
A(0xD814, CPR2_2U, TRICORE_FEATURE_13)
|
||||
A(0xD818, CPR2_3L, TRICORE_FEATURE_13)
|
||||
A(0xD81C, CPR2_3U, TRICORE_FEATURE_13)
|
||||
A(0xDC00, CPR3_0L, TRICORE_FEATURE_13)
|
||||
A(0xDC04, CPR3_0U, TRICORE_FEATURE_13)
|
||||
A(0xDC08, CPR3_1L, TRICORE_FEATURE_13)
|
||||
A(0xDC0C, CPR3_1U, TRICORE_FEATURE_13)
|
||||
A(0xDC10, CPR3_2L, TRICORE_FEATURE_13)
|
||||
A(0xDC14, CPR3_2U, TRICORE_FEATURE_13)
|
||||
A(0xDC18, CPR3_3L, TRICORE_FEATURE_13)
|
||||
A(0xDC1C, CPR3_3U, TRICORE_FEATURE_13)
|
||||
A(0xE000, DPM0, TRICORE_FEATURE_13)
|
||||
A(0xE080, DPM1, TRICORE_FEATURE_13)
|
||||
A(0xE100, DPM2, TRICORE_FEATURE_13)
|
||||
A(0xE180, DPM3, TRICORE_FEATURE_13)
|
||||
A(0xE200, CPM0, TRICORE_FEATURE_13)
|
||||
A(0xE280, CPM1, TRICORE_FEATURE_13)
|
||||
A(0xE300, CPM2, TRICORE_FEATURE_13)
|
||||
A(0xE380, CPM3, TRICORE_FEATURE_13)
|
||||
/* memory Managment Registers */
|
||||
A(0x8000, MMU_CON, TRICORE_FEATURE_13)
|
||||
A(0x8004, MMU_ASI, TRICORE_FEATURE_13)
|
||||
A(0x800C, MMU_TVA, TRICORE_FEATURE_13)
|
||||
A(0x8010, MMU_TPA, TRICORE_FEATURE_13)
|
||||
A(0x8014, MMU_TPX, TRICORE_FEATURE_13)
|
||||
A(0x8018, MMU_TFA, TRICORE_FEATURE_13)
|
||||
E(0x9004, BMACON, TRICORE_FEATURE_131)
|
||||
E(0x900C, SMACON, TRICORE_FEATURE_131)
|
||||
A(0x9020, DIEAR, TRICORE_FEATURE_131)
|
||||
A(0x9024, DIETR, TRICORE_FEATURE_131)
|
||||
A(0x9028, CCDIER, TRICORE_FEATURE_131)
|
||||
E(0x9044, MIECON, TRICORE_FEATURE_131)
|
||||
A(0x9210, PIEAR, TRICORE_FEATURE_131)
|
||||
A(0x9214, PIETR, TRICORE_FEATURE_131)
|
||||
A(0x9218, CCPIER, TRICORE_FEATURE_131)
|
||||
/* debug registers */
|
||||
A(0xFD00, DBGSR, TRICORE_FEATURE_13)
|
||||
A(0xFD08, EXEVT, TRICORE_FEATURE_13)
|
||||
A(0xFD0C, CREVT, TRICORE_FEATURE_13)
|
||||
A(0xFD10, SWEVT, TRICORE_FEATURE_13)
|
||||
A(0xFD20, TR0EVT, TRICORE_FEATURE_13)
|
||||
A(0xFD24, TR1EVT, TRICORE_FEATURE_13)
|
||||
A(0xFD40, DMS, TRICORE_FEATURE_13)
|
||||
A(0xFD44, DCX, TRICORE_FEATURE_13)
|
||||
A(0xFD48, DBGTCR, TRICORE_FEATURE_131)
|
||||
A(0xFC00, CCTRL, TRICORE_FEATURE_131)
|
||||
A(0xFC04, CCNT, TRICORE_FEATURE_131)
|
||||
A(0xFC08, ICNT, TRICORE_FEATURE_131)
|
||||
A(0xFC0C, M1CNT, TRICORE_FEATURE_131)
|
||||
A(0xFC10, M2CNT, TRICORE_FEATURE_131)
|
||||
A(0xFC14, M3CNT, TRICORE_FEATURE_131)
|
@ -36,3 +36,6 @@ DEF_HELPER_2(stucx, void, env, i32)
|
||||
/* Address mode helper */
|
||||
DEF_HELPER_1(br_update, i32, i32)
|
||||
DEF_HELPER_2(circ_update, i32, i32, i32)
|
||||
/* PSW cache helper */
|
||||
DEF_HELPER_2(psw_write, void, env, i32)
|
||||
DEF_HELPER_1(psw_read, i32, env)
|
||||
|
@ -536,6 +536,17 @@ void helper_stucx(CPUTriCoreState *env, uint32_t ea)
|
||||
save_context_upper(env, ea);
|
||||
}
|
||||
|
||||
void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
psw_write(env, arg);
|
||||
}
|
||||
|
||||
uint32_t helper_psw_read(CPUTriCoreState *env)
|
||||
{
|
||||
return psw_read(env);
|
||||
}
|
||||
|
||||
|
||||
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
|
||||
uint32_t exception,
|
||||
int error_code,
|
||||
|
@ -233,6 +233,63 @@ static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
|
||||
tcg_temp_free(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. */
|
||||
#define R(ADDRESS, REG, FEATURE) \
|
||||
case ADDRESS: \
|
||||
if (tricore_feature(env, FEATURE)) { \
|
||||
tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
|
||||
} \
|
||||
break;
|
||||
#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
|
||||
#define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
|
||||
static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
|
||||
{
|
||||
/* since we're caching PSW make this a special case */
|
||||
if (offset == 0xfe04) {
|
||||
gen_helper_psw_read(ret, cpu_env);
|
||||
} else {
|
||||
switch (offset) {
|
||||
#include "csfr.def"
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef R
|
||||
#undef A
|
||||
#undef E
|
||||
|
||||
#define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
|
||||
since no execption occurs */
|
||||
#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE) \
|
||||
case ADDRESS: \
|
||||
if (tricore_feature(env, FEATURE)) { \
|
||||
tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG)); \
|
||||
} \
|
||||
break;
|
||||
/* Endinit protected registers
|
||||
TODO: Since the endinit bit is in a register of a not yet implemented
|
||||
watchdog device, we handle endinit protected registers like
|
||||
all-access registers for now. */
|
||||
#define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
|
||||
static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1,
|
||||
int32_t offset)
|
||||
{
|
||||
if (ctx->hflags & TRICORE_HFLAG_SM) {
|
||||
/* since we're caching PSW make this a special case */
|
||||
if (offset == 0xfe04) {
|
||||
gen_helper_psw_write(cpu_env, r1);
|
||||
} else {
|
||||
switch (offset) {
|
||||
#include "csfr.def"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* generate privilege trap */
|
||||
}
|
||||
}
|
||||
|
||||
/* Functions for arithmetic instructions */
|
||||
|
||||
static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
|
||||
@ -3227,6 +3284,50 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
|
||||
tcg_temp_free(temp2);
|
||||
}
|
||||
|
||||
/* RLC format */
|
||||
|
||||
static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
|
||||
uint32_t op1)
|
||||
{
|
||||
int32_t const16;
|
||||
int r1, r2;
|
||||
|
||||
const16 = MASK_OP_RLC_CONST16_SEXT(ctx->opcode);
|
||||
r1 = MASK_OP_RLC_S1(ctx->opcode);
|
||||
r2 = MASK_OP_RLC_D(ctx->opcode);
|
||||
|
||||
switch (op1) {
|
||||
case OPC1_32_RLC_ADDI:
|
||||
gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16);
|
||||
break;
|
||||
case OPC1_32_RLC_ADDIH:
|
||||
gen_addi_CC(cpu_gpr_d[r2], cpu_gpr_d[r1], const16 << 16);
|
||||
break;
|
||||
case OPC1_32_RLC_ADDIH_A:
|
||||
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
|
||||
break;
|
||||
case OPC1_32_RLC_MFCR:
|
||||
gen_mfcr(env, cpu_gpr_d[r2], const16);
|
||||
break;
|
||||
case OPC1_32_RLC_MOV:
|
||||
tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
|
||||
break;
|
||||
case OPC1_32_RLC_MOV_U:
|
||||
const16 = MASK_OP_RLC_CONST16(ctx->opcode);
|
||||
tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
|
||||
break;
|
||||
case OPC1_32_RLC_MOV_H:
|
||||
tcg_gen_movi_tl(cpu_gpr_d[r2], const16 << 16);
|
||||
break;
|
||||
case OPC1_32_RLC_MOVH_A:
|
||||
tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
|
||||
break;
|
||||
case OPC1_32_RLC_MTCR:
|
||||
gen_mtcr(env, ctx, cpu_gpr_d[r2], const16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||
{
|
||||
int op1;
|
||||
@ -3435,6 +3536,18 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||
case OPCM_32_RCRW_MASK_INSERT:
|
||||
decode_rcrw_insert(env, ctx);
|
||||
break;
|
||||
/* RLC Format */
|
||||
case OPC1_32_RLC_ADDI:
|
||||
case OPC1_32_RLC_ADDIH:
|
||||
case OPC1_32_RLC_ADDIH_A:
|
||||
case OPC1_32_RLC_MFCR:
|
||||
case OPC1_32_RLC_MOV:
|
||||
case OPC1_32_RLC_MOV_U:
|
||||
case OPC1_32_RLC_MOV_H:
|
||||
case OPC1_32_RLC_MOVH_A:
|
||||
case OPC1_32_RLC_MTCR:
|
||||
decode_rlc_opc(env, ctx, op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,6 +192,7 @@
|
||||
|
||||
#define MASK_OP_RLC_D(op) MASK_OP_META_D(op)
|
||||
#define MASK_OP_RLC_CONST16(op) MASK_BITS_SHIFT(op, 12, 27)
|
||||
#define MASK_OP_RLC_CONST16_SEXT(op) MASK_BITS_SHIFT_SEXT(op, 12, 27)
|
||||
#define MASK_OP_RLC_S1(op) MASK_OP_META_S1(op)
|
||||
|
||||
/* RR Format */
|
||||
|
Loading…
Reference in New Issue
Block a user