wip! status register management

This commit is contained in:
fridtjof 2025-08-15 17:35:53 +02:00
parent ecdcafd570
commit 7037504166
3 changed files with 127 additions and 12 deletions

View file

@ -59,7 +59,11 @@ static void cr16c_cpu_reset_hold(Object *obj, ResetType type)
env->psr_f = 0; env->psr_f = 0;
env->psr_l = 0; env->psr_l = 0;
env->psr_c = 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; 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, "SP: " TARGET_FMT_lx "\n", env->r[CR16C_REGNO_SP]);
qemu_fprintf(f, "-- Flags --\n"); qemu_fprintf(f, "-- Flags --\n");
qemu_fprintf(f, "N: %2d\n", env->psr_n); qemu_fprintf(f, "PSR: %04x\n", cr16c_cpu_pack_psr(env));
qemu_fprintf(f, "Z: %2d\n", env->psr_z); qemu_fprintf(f, ". I P E N Z F U L T C\n");
qemu_fprintf(f, "F: %2d\n", env->psr_f); qemu_fprintf(f, ". %d %d %d %d %d %d %d %d %d %d\n",
qemu_fprintf(f, "L: %2d\n", env->psr_l); 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, "C: %2d\n", 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"); qemu_fprintf(f, "\n");
} }

View file

@ -4,6 +4,36 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "cpu-qom.h" #include "cpu-qom.h"
#include "exec/cpu-defs.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_REG_COUNT 16
#define CR16C_FIRST_32B_REG 12 #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 r[CR16C_REG_COUNT]; /* General purpose registers: 12x16-bit + 2x32-bit */
uint32_t psr_n; uint32_t psr_n; // Negative bit
uint32_t psr_z; uint32_t psr_z; // Zero bit
uint32_t psr_f; uint32_t psr_f; // Flag bit
uint32_t psr_l; uint32_t psr_l; // Low flag bit
uint32_t psr_c; 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; } CPUCR16CState;
struct ArchCPU { 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, void cr16c_restore_state_to_opc(CPUState *cpu, const TranslationBlock *tb,
const uint64_t *data); 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 #endif // !QEMU_CR16C_CPU_H

View file

@ -66,12 +66,37 @@ typedef struct DisasContext {
/* Registers */ /* 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_n;
static TCGv psr_z; static TCGv psr_z;
static TCGv psr_f; static TCGv psr_f;
static TCGv psr_l; static TCGv psr_l;
static TCGv psr_c; 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]; 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_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_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_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, void cr16c_translate_code(CPUState *cs, TranslationBlock *tb,