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:
Bastian Koppelmann 2014-10-30 12:06:53 +00:00
parent ed51626066
commit 2b2f7d97d8
5 changed files with 252 additions and 0 deletions

124
target-tricore/csfr.def Normal file
View 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)

View File

@ -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)

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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 */