diff --git a/target/cr16c/cpu.c b/target/cr16c/cpu.c index ee2bce1282..4e2f1d681f 100644 --- a/target/cr16c/cpu.c +++ b/target/cr16c/cpu.c @@ -59,7 +59,11 @@ static void cr16c_cpu_reset_hold(Object *obj, ResetType type) env->psr_f = 0; env->psr_l = 0; env->psr_c = 0; - // TODO: Rest of flags from PSR once implemented + env->psr_t = 0; + env->psr_u = 0; + env->psr_e = 0; + env->psr_p = 0; + env->psr_i = 0; env->pc = 0; } @@ -97,11 +101,14 @@ static void cr16c_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "SP: " TARGET_FMT_lx "\n", env->r[CR16C_REGNO_SP]); qemu_fprintf(f, "-- Flags --\n"); - qemu_fprintf(f, "N: %2d\n", env->psr_n); - qemu_fprintf(f, "Z: %2d\n", env->psr_z); - qemu_fprintf(f, "F: %2d\n", env->psr_f); - qemu_fprintf(f, "L: %2d\n", env->psr_l); - qemu_fprintf(f, "C: %2d\n", env->psr_c); + qemu_fprintf(f, "PSR: %04x\n", cr16c_cpu_pack_psr(env)); + qemu_fprintf(f, ". I P E N Z F U L T C\n"); + qemu_fprintf(f, ". %d %d %d %d %d %d %d %d %d %d\n", + env->psr_i, env->psr_p, env->psr_e, env->psr_n, env->psr_z, env->psr_f, env->psr_u, env->psr_l, env->psr_t, env->psr_c); + qemu_fprintf(f, "CFG: %04x\n", cr16c_cpu_pack_cfg(env)); + qemu_fprintf(f, ". SR ED LIC IC DC\n"); + qemu_fprintf(f, ". %d %d %d %d %d\n", + env->cfg_sr, env->cfg_ed, env->cfg_lic, env->cfg_ic, env->cfg_dc); qemu_fprintf(f, "\n"); } diff --git a/target/cr16c/cpu.h b/target/cr16c/cpu.h index b43969e866..4f7afba78c 100644 --- a/target/cr16c/cpu.h +++ b/target/cr16c/cpu.h @@ -4,6 +4,36 @@ #include "qemu/osdep.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" +#include "hw/registerfields.h" + +/* PSR define */ +REG16(PSR, 0) +FIELD(PSR, C, 0, 1) +FIELD(PSR, T, 1, 1) +FIELD(PSR, L, 2, 1) +FIELD(PSR, U, 3, 1) +// bit 4 is reserved +FIELD(PSR, F, 5, 1) +FIELD(PSR, Z, 6, 1) +FIELD(PSR, N, 7, 1) +// bit 8 is reserved +FIELD(PSR, E, 9, 1) +FIELD(PSR, P, 10, 1) +FIELD(PSR, I, 11, 1) +// 12-15 are reserved as well + +/* CFG define */ +REG16(CFG, 0) +// bit 0, 1 are fixed 0 +FIELD(CFG, DC, 2, 1) +FIELD(CFG, LDC, 3, 1) +FIELD(CFG, IC, 4, 1) +FIELD(CFG, LIC, 5, 1) +// bit 6, 7 are fixed 0 +FIELD(CFG, ED, 8, 1) +FIELD(CFG, SR, 9, 1) +// bit 10-15 are reserved + #define CR16C_REG_COUNT 16 #define CR16C_FIRST_32B_REG 12 @@ -25,11 +55,24 @@ typedef struct CPUArchState { uint32_t r[CR16C_REG_COUNT]; /* General purpose registers: 12x16-bit + 2x32-bit */ - uint32_t psr_n; - uint32_t psr_z; - uint32_t psr_f; - uint32_t psr_l; - uint32_t psr_c; + uint32_t psr_n; // Negative bit + uint32_t psr_z; // Zero bit + uint32_t psr_f; // Flag bit + uint32_t psr_l; // Low flag bit + uint32_t psr_c; // Carry bit + + uint32_t psr_t; // Trace bit + uint32_t psr_u; // User mode bit + uint32_t psr_e; // local maskable interrupt Enable bit + uint32_t psr_p; // trace trap Pending bit + uint32_t psr_i; // global maskable Interrupt enable bit + + uint32_t cfg_dc; // Data Cache bit + uint32_t cfg_ldc; // Lock Data Cache bit + uint32_t cfg_ic; // Instruction Cache bit + uint32_t cfg_lic; // Lock Instruction Cache bit + uint32_t cfg_ed; // Extended Dispatch bit + uint32_t cfg_sr; // Short Register bit } CPUCR16CState; struct ArchCPU { @@ -63,4 +106,32 @@ void cr16c_translate_code(CPUState *cs, TranslationBlock *tb, void cr16c_restore_state_to_opc(CPUState *cpu, const TranslationBlock *tb, const uint64_t *data); +static inline uint32_t cr16c_cpu_pack_psr(const CPUCR16CState *env) +{ + uint32_t psr = 0; + psr = FIELD_DP32(psr, PSR, C, env->psr_c); + psr = FIELD_DP32(psr, PSR, T, env->psr_t); + psr = FIELD_DP32(psr, PSR, L, env->psr_l); + psr = FIELD_DP32(psr, PSR, U, env->psr_u); + psr = FIELD_DP32(psr, PSR, N, env->psr_n); + psr = FIELD_DP32(psr, PSR, Z, env->psr_z); + psr = FIELD_DP32(psr, PSR, F, env->psr_f); + psr = FIELD_DP32(psr, PSR, E, env->psr_e); + psr = FIELD_DP32(psr, PSR, P, env->psr_p); + psr = FIELD_DP32(psr, PSR, I, env->psr_i); + return psr; +} + +static inline uint32_t cr16c_cpu_pack_cfg(const CPUCR16CState *env) +{ + uint32_t cfg = 0; + cfg = FIELD_DP32(cfg, CFG, DC, env->cfg_dc); + cfg = FIELD_DP32(cfg, CFG, LDC, env->cfg_ldc); + cfg = FIELD_DP32(cfg, CFG, IC, env->cfg_ic); + cfg = FIELD_DP32(cfg, CFG, LIC, env->cfg_lic); + cfg = FIELD_DP32(cfg, CFG, ED, env->cfg_ed); + cfg = FIELD_DP32(cfg, CFG, SR, env->cfg_sr); + return cfg; +} + #endif // !QEMU_CR16C_CPU_H diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index 4e1cfb8675..3adeed5f4c 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -66,12 +66,37 @@ typedef struct DisasContext { /* Registers */ -static TCGv pc; +static TCGv pc; // 24 bit +// ISPH/L (Interrupt Stack Pointer) +// USPH/L (User Stack Pointer) +// INTBASEH/L (Interrupt Base) + +// PSR 16 +// these flags are part of PSR static TCGv psr_n; static TCGv psr_z; static TCGv psr_f; static TCGv psr_l; static TCGv psr_c; +static TCGv psr_t; +static TCGv psr_u; +static TCGv psr_e; +static TCGv psr_p; +static TCGv psr_i; + +// CFG +// Most notably: SR bit "Short Register" +// => switches to register pairings for reassembled code originally written for CR16B +static TCGv cfg_dc; +static TCGv cfg_ldc; +static TCGv cfg_ic; +static TCGv cfg_lic; +static TCGv cfg_ed; +static TCGv cfg_sr; + +// debug registers (optional) "depends on the configuration of the chip" + +/* General purpose registers, incl. RA and SP */ static TCGv r[CR16C_REG_COUNT]; @@ -1646,6 +1671,18 @@ void cr16c_translate_init(void) { psr_f = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_f), "psr_f"); psr_l = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_l), "psr_l"); psr_c = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_c), "psr_c"); + psr_t = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_t), "psr_t"); + psr_u = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_u), "psr_u"); + psr_e = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_e), "psr_e"); + psr_p = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_p), "psr_p"); + psr_i = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, psr_i), "psr_i"); + + cfg_dc = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_dc), "cfg_dc"); + cfg_ldc = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_ldc), "cfg_ldc"); + cfg_ic = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_ic), "cfg_ic"); + cfg_lic = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_lic), "cfg_lic"); + cfg_ed = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_ed), "cfg_ed"); + cfg_sr = tcg_global_mem_new_i32(tcg_env, offsetof(CPUCR16CState, cfg_sr), "cfg_sr"); } void cr16c_translate_code(CPUState *cs, TranslationBlock *tb,