mirror of https://github.com/xemu-project/xemu.git
cris: Add support for CRISv10 translation.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
parent
46e246c911
commit
40e9eddd38
|
@ -262,4 +262,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
|
||||||
| X_FLAG | PFIX_FLAG));
|
| X_FLAG | PFIX_FLAG));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define cpu_list cris_cpu_list
|
||||||
|
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* CRISv10 insn decoding macros.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 AXIS Communications AB
|
||||||
|
* Written by Edgar E. Iglesias.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CRISV10_MODE_QIMMEDIATE 0
|
||||||
|
#define CRISV10_MODE_REG 1
|
||||||
|
#define CRISV10_MODE_INDIRECT 2
|
||||||
|
#define CRISV10_MODE_AUTOINC 3
|
||||||
|
|
||||||
|
/* Quick Immediate. */
|
||||||
|
#define CRISV10_QIMM_BCC_R0 0
|
||||||
|
#define CRISV10_QIMM_BCC_R1 1
|
||||||
|
#define CRISV10_QIMM_BCC_R2 2
|
||||||
|
#define CRISV10_QIMM_BCC_R3 3
|
||||||
|
|
||||||
|
#define CRISV10_QIMM_BDAP_R0 4
|
||||||
|
#define CRISV10_QIMM_BDAP_R1 5
|
||||||
|
#define CRISV10_QIMM_BDAP_R2 6
|
||||||
|
#define CRISV10_QIMM_BDAP_R3 7
|
||||||
|
|
||||||
|
#define CRISV10_QIMM_ADDQ 8
|
||||||
|
#define CRISV10_QIMM_MOVEQ 9
|
||||||
|
#define CRISV10_QIMM_SUBQ 10
|
||||||
|
#define CRISV10_QIMM_CMPQ 11
|
||||||
|
#define CRISV10_QIMM_ANDQ 12
|
||||||
|
#define CRISV10_QIMM_ORQ 13
|
||||||
|
#define CRISV10_QIMM_ASHQ 14
|
||||||
|
#define CRISV10_QIMM_LSHQ 15
|
||||||
|
|
||||||
|
|
||||||
|
#define CRISV10_REG_ADDX 0
|
||||||
|
#define CRISV10_REG_MOVX 1
|
||||||
|
#define CRISV10_REG_SUBX 2
|
||||||
|
#define CRISV10_REG_LSL 3
|
||||||
|
#define CRISV10_REG_ADDI 4
|
||||||
|
#define CRISV10_REG_BIAP 5
|
||||||
|
#define CRISV10_REG_NEG 6
|
||||||
|
#define CRISV10_REG_BOUND 7
|
||||||
|
#define CRISV10_REG_ADD 8
|
||||||
|
#define CRISV10_REG_MOVE_R 9
|
||||||
|
#define CRISV10_REG_MOVE_SPR_R 9
|
||||||
|
#define CRISV10_REG_MOVE_R_SPR 8
|
||||||
|
#define CRISV10_REG_SUB 10
|
||||||
|
#define CRISV10_REG_CMP 11
|
||||||
|
#define CRISV10_REG_AND 12
|
||||||
|
#define CRISV10_REG_OR 13
|
||||||
|
#define CRISV10_REG_ASR 14
|
||||||
|
#define CRISV10_REG_LSR 15
|
||||||
|
|
||||||
|
#define CRISV10_REG_BTST 3
|
||||||
|
#define CRISV10_REG_SCC 4
|
||||||
|
#define CRISV10_REG_SETF 6
|
||||||
|
#define CRISV10_REG_CLEARF 7
|
||||||
|
#define CRISV10_REG_BIAP 5
|
||||||
|
#define CRISV10_REG_ABS 10
|
||||||
|
#define CRISV10_REG_DSTEP 11
|
||||||
|
#define CRISV10_REG_LZ 12
|
||||||
|
#define CRISV10_REG_NOT 13
|
||||||
|
#define CRISV10_REG_SWAP 13
|
||||||
|
#define CRISV10_REG_XOR 14
|
||||||
|
#define CRISV10_REG_MSTEP 15
|
||||||
|
|
||||||
|
/* Indirect, var size. */
|
||||||
|
#define CRISV10_IND_TEST 14
|
||||||
|
#define CRISV10_IND_MUL 4
|
||||||
|
#define CRISV10_IND_BDAP_M 5
|
||||||
|
#define CRISV10_IND_ADD 8
|
||||||
|
#define CRISV10_IND_MOVE_M_R 9
|
||||||
|
|
||||||
|
|
||||||
|
/* indirect fixed size. */
|
||||||
|
#define CRISV10_IND_ADDX 0
|
||||||
|
#define CRISV10_IND_MOVX 1
|
||||||
|
#define CRISV10_IND_SUBX 2
|
||||||
|
#define CRISV10_IND_CMPX 3
|
||||||
|
#define CRISV10_IND_JUMP_M 4
|
||||||
|
#define CRISV10_IND_DIP 5
|
||||||
|
#define CRISV10_IND_JUMP_R 6
|
||||||
|
#define CRISV10_IND_BOUND 7
|
||||||
|
#define CRISV10_IND_BCC_M 7
|
||||||
|
#define CRISV10_IND_MOVE_M_SPR 8
|
||||||
|
#define CRISV10_IND_MOVE_SPR_M 9
|
||||||
|
#define CRISV10_IND_SUB 10
|
||||||
|
#define CRISV10_IND_CMP 11
|
||||||
|
#define CRISV10_IND_AND 12
|
||||||
|
#define CRISV10_IND_OR 13
|
||||||
|
#define CRISV10_IND_MOVE_R_M 15
|
||||||
|
|
||||||
|
#define CRISV10_IND_MOVEM_M_R 14
|
||||||
|
#define CRISV10_IND_MOVEM_R_M 15
|
||||||
|
|
|
@ -86,6 +86,7 @@ typedef struct DisasContext {
|
||||||
target_ulong pc, ppc;
|
target_ulong pc, ppc;
|
||||||
|
|
||||||
/* Decoder. */
|
/* Decoder. */
|
||||||
|
unsigned int (*decoder)(struct DisasContext *dc);
|
||||||
uint32_t ir;
|
uint32_t ir;
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
unsigned int op1;
|
unsigned int op1;
|
||||||
|
@ -94,6 +95,11 @@ typedef struct DisasContext {
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
unsigned int postinc;
|
unsigned int postinc;
|
||||||
|
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int src;
|
||||||
|
unsigned int dst;
|
||||||
|
unsigned int cond;
|
||||||
|
|
||||||
int update_cc;
|
int update_cc;
|
||||||
int cc_op;
|
int cc_op;
|
||||||
int cc_size;
|
int cc_size;
|
||||||
|
@ -108,6 +114,8 @@ typedef struct DisasContext {
|
||||||
int flags_x;
|
int flags_x;
|
||||||
|
|
||||||
int clear_x; /* Clear x after this insn? */
|
int clear_x; /* Clear x after this insn? */
|
||||||
|
int clear_prefix; /* Clear prefix after this insn? */
|
||||||
|
int clear_locked_irq; /* Clear the irq lockout. */
|
||||||
int cpustate_changed;
|
int cpustate_changed;
|
||||||
unsigned int tb_flags; /* tb dependent flags. */
|
unsigned int tb_flags; /* tb dependent flags. */
|
||||||
int is_jmp;
|
int is_jmp;
|
||||||
|
@ -219,6 +227,12 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cris_lock_irq(DisasContext *dc)
|
||||||
|
{
|
||||||
|
dc->clear_locked_irq = 0;
|
||||||
|
t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void t_gen_raise_exception(uint32_t index)
|
static inline void t_gen_raise_exception(uint32_t index)
|
||||||
{
|
{
|
||||||
TCGv_i32 tmp = tcg_const_i32(index);
|
TCGv_i32 tmp = tcg_const_i32(index);
|
||||||
|
@ -332,6 +346,24 @@ static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
|
||||||
gen_set_label(l1);
|
gen_set_label(l1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
|
||||||
|
{
|
||||||
|
TCGv t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* d <<= 1
|
||||||
|
* if (n)
|
||||||
|
* d += s;
|
||||||
|
*/
|
||||||
|
t = tcg_temp_new();
|
||||||
|
tcg_gen_shli_tl(d, a, 1);
|
||||||
|
tcg_gen_shli_tl(t, ccs, 31 - 3);
|
||||||
|
tcg_gen_sari_tl(t, t, 31);
|
||||||
|
tcg_gen_and_tl(t, t, b);
|
||||||
|
tcg_gen_add_tl(d, d, t);
|
||||||
|
tcg_temp_free(t);
|
||||||
|
}
|
||||||
|
|
||||||
/* Extended arithmetics on CRIS. */
|
/* Extended arithmetics on CRIS. */
|
||||||
static inline void t_gen_add_flag(TCGv d, int flag)
|
static inline void t_gen_add_flag(TCGv d, int flag)
|
||||||
{
|
{
|
||||||
|
@ -634,7 +666,7 @@ static void cris_evaluate_flags(DisasContext *dc)
|
||||||
if (dc->flags_x)
|
if (dc->flags_x)
|
||||||
tcg_gen_ori_tl(cpu_PR[PR_CCS],
|
tcg_gen_ori_tl(cpu_PR[PR_CCS],
|
||||||
cpu_PR[PR_CCS], X_FLAG);
|
cpu_PR[PR_CCS], X_FLAG);
|
||||||
else
|
else if (dc->cc_op == CC_OP_FLAGS)
|
||||||
tcg_gen_andi_tl(cpu_PR[PR_CCS],
|
tcg_gen_andi_tl(cpu_PR[PR_CCS],
|
||||||
cpu_PR[PR_CCS], ~X_FLAG);
|
cpu_PR[PR_CCS], ~X_FLAG);
|
||||||
}
|
}
|
||||||
|
@ -774,6 +806,9 @@ static void cris_alu_op_exec(DisasContext *dc, int op,
|
||||||
case CC_OP_DSTEP:
|
case CC_OP_DSTEP:
|
||||||
t_gen_cris_dstep(dst, a, b);
|
t_gen_cris_dstep(dst, a, b);
|
||||||
break;
|
break;
|
||||||
|
case CC_OP_MSTEP:
|
||||||
|
t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
|
||||||
|
break;
|
||||||
case CC_OP_BOUND:
|
case CC_OP_BOUND:
|
||||||
{
|
{
|
||||||
int l1;
|
int l1;
|
||||||
|
@ -878,7 +913,8 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
|
||||||
move_opt = (dc->cc_op == CC_OP_MOVE);
|
move_opt = (dc->cc_op == CC_OP_MOVE);
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
case CC_EQ:
|
case CC_EQ:
|
||||||
if (arith_opt || move_opt) {
|
if ((arith_opt || move_opt)
|
||||||
|
&& dc->cc_x_uptodate != (2 | X_FLAG)) {
|
||||||
/* If cc_result is zero, T0 should be
|
/* If cc_result is zero, T0 should be
|
||||||
non-zero otherwise T0 should be zero. */
|
non-zero otherwise T0 should be zero. */
|
||||||
int l1;
|
int l1;
|
||||||
|
@ -896,9 +932,10 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CC_NE:
|
case CC_NE:
|
||||||
if (arith_opt || move_opt)
|
if ((arith_opt || move_opt)
|
||||||
|
&& dc->cc_x_uptodate != (2 | X_FLAG)) {
|
||||||
tcg_gen_mov_tl(cc, cc_result);
|
tcg_gen_mov_tl(cc, cc_result);
|
||||||
else {
|
} else {
|
||||||
cris_evaluate_flags(dc);
|
cris_evaluate_flags(dc);
|
||||||
tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
|
tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
|
||||||
Z_FLAG);
|
Z_FLAG);
|
||||||
|
@ -2058,16 +2095,17 @@ static unsigned int dec_setclrf(DisasContext *dc)
|
||||||
dc->flags_x = 0;
|
dc->flags_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Break the TB if the P flag changes. */
|
/* Break the TB if any of the SPI flag changes. */
|
||||||
if (flags & P_FLAG) {
|
if (flags & (P_FLAG | S_FLAG)) {
|
||||||
if ((set && !(dc->tb_flags & P_FLAG))
|
tcg_gen_movi_tl(env_pc, dc->pc + 2);
|
||||||
|| (!set && (dc->tb_flags & P_FLAG))) {
|
dc->is_jmp = DISAS_UPDATE;
|
||||||
tcg_gen_movi_tl(env_pc, dc->pc + 2);
|
dc->cpustate_changed = 1;
|
||||||
dc->is_jmp = DISAS_UPDATE;
|
|
||||||
dc->cpustate_changed = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (flags & S_FLAG) {
|
|
||||||
|
/* For the I flag, only act on posedge. */
|
||||||
|
if ((flags & I_FLAG)) {
|
||||||
|
tcg_gen_movi_tl(env_pc, dc->pc + 2);
|
||||||
|
dc->is_jmp = DISAS_UPDATE;
|
||||||
dc->cpustate_changed = 1;
|
dc->cpustate_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2143,17 +2181,22 @@ static unsigned int dec_move_rp(DisasContext *dc)
|
||||||
static unsigned int dec_move_pr(DisasContext *dc)
|
static unsigned int dec_move_pr(DisasContext *dc)
|
||||||
{
|
{
|
||||||
TCGv t0;
|
TCGv t0;
|
||||||
LOG_DIS("move $p%u, $r%u\n", dc->op1, dc->op2);
|
LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
|
||||||
cris_cc_mask(dc, 0);
|
cris_cc_mask(dc, 0);
|
||||||
|
|
||||||
if (dc->op2 == PR_CCS)
|
if (dc->op2 == PR_CCS)
|
||||||
cris_evaluate_flags(dc);
|
cris_evaluate_flags(dc);
|
||||||
|
|
||||||
t0 = tcg_temp_new();
|
if (dc->op2 == PR_DZ) {
|
||||||
t_gen_mov_TN_preg(t0, dc->op2);
|
tcg_gen_movi_tl(cpu_R[dc->op1], 0);
|
||||||
cris_alu(dc, CC_OP_MOVE,
|
} else {
|
||||||
cpu_R[dc->op1], cpu_R[dc->op1], t0, preg_sizes[dc->op2]);
|
t0 = tcg_temp_new();
|
||||||
tcg_temp_free(t0);
|
t_gen_mov_TN_preg(t0, dc->op2);
|
||||||
|
cris_alu(dc, CC_OP_MOVE,
|
||||||
|
cpu_R[dc->op1], cpu_R[dc->op1], t0,
|
||||||
|
preg_sizes[dc->op2]);
|
||||||
|
tcg_temp_free(t0);
|
||||||
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3026,8 +3069,7 @@ static struct decoder_info {
|
||||||
{{0, 0}, dec_null}
|
{{0, 0}, dec_null}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned int
|
static unsigned int crisv32_decoder(DisasContext *dc)
|
||||||
cris_decoder(DisasContext *dc)
|
|
||||||
{
|
{
|
||||||
unsigned int insn_len = 2;
|
unsigned int insn_len = 2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -3090,6 +3132,7 @@ static void check_breakpoint(CPUState *env, DisasContext *dc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "translate_v10.c"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delay slots on QEMU/CRIS.
|
* Delay slots on QEMU/CRIS.
|
||||||
|
@ -3132,7 +3175,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
{
|
{
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
uint32_t pc_start;
|
uint32_t pc_start;
|
||||||
unsigned int insn_len;
|
unsigned int insn_len, orig_flags;
|
||||||
int j, lj;
|
int j, lj;
|
||||||
struct DisasContext ctx;
|
struct DisasContext ctx;
|
||||||
struct DisasContext *dc = &ctx;
|
struct DisasContext *dc = &ctx;
|
||||||
|
@ -3143,6 +3186,11 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
|
|
||||||
qemu_log_try_set_file(stderr);
|
qemu_log_try_set_file(stderr);
|
||||||
|
|
||||||
|
if (env->pregs[PR_VR] == 32)
|
||||||
|
dc->decoder = crisv32_decoder;
|
||||||
|
else
|
||||||
|
dc->decoder = crisv10_decoder;
|
||||||
|
|
||||||
/* Odd PC indicates that branch is rexecuting due to exception in the
|
/* Odd PC indicates that branch is rexecuting due to exception in the
|
||||||
* delayslot, like in real hw.
|
* delayslot, like in real hw.
|
||||||
*/
|
*/
|
||||||
|
@ -3162,12 +3210,15 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
dc->cc_x_uptodate = 0;
|
dc->cc_x_uptodate = 0;
|
||||||
dc->cc_mask = 0;
|
dc->cc_mask = 0;
|
||||||
dc->update_cc = 0;
|
dc->update_cc = 0;
|
||||||
|
dc->clear_prefix = 0;
|
||||||
|
dc->clear_locked_irq = 1;
|
||||||
|
|
||||||
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
|
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
|
||||||
dc->cc_size_uptodate = -1;
|
dc->cc_size_uptodate = -1;
|
||||||
|
|
||||||
/* Decode TB flags. */
|
/* Decode TB flags. */
|
||||||
dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
|
orig_flags = dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
|
||||||
|
| X_FLAG | PFIX_FLAG);
|
||||||
dc->delayed_branch = !!(tb->flags & 7);
|
dc->delayed_branch = !!(tb->flags & 7);
|
||||||
if (dc->delayed_branch)
|
if (dc->delayed_branch)
|
||||||
dc->jmp = JMP_INDIRECT;
|
dc->jmp = JMP_INDIRECT;
|
||||||
|
@ -3233,7 +3284,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
gen_io_start();
|
gen_io_start();
|
||||||
dc->clear_x = 1;
|
dc->clear_x = 1;
|
||||||
|
|
||||||
insn_len = cris_decoder(dc);
|
insn_len = dc->decoder(dc);
|
||||||
dc->ppc = dc->pc;
|
dc->ppc = dc->pc;
|
||||||
dc->pc += insn_len;
|
dc->pc += insn_len;
|
||||||
if (dc->clear_x)
|
if (dc->clear_x)
|
||||||
|
@ -3271,6 +3322,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
&& (dc->pc < next_page_start)
|
&& (dc->pc < next_page_start)
|
||||||
&& num_insns < max_insns);
|
&& num_insns < max_insns);
|
||||||
|
|
||||||
|
if (dc->tb_flags != orig_flags) {
|
||||||
|
dc->cpustate_changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dc->clear_locked_irq)
|
||||||
|
t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
|
||||||
|
|
||||||
npc = dc->pc;
|
npc = dc->pc;
|
||||||
if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
|
if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
|
||||||
npc = dc->jmp_pc;
|
npc = dc->jmp_pc;
|
||||||
|
@ -3330,7 +3388,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||||
#ifdef DEBUG_DISAS
|
#ifdef DEBUG_DISAS
|
||||||
#if !DISAS_CRIS
|
#if !DISAS_CRIS
|
||||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||||
log_target_disas(pc_start, dc->pc - pc_start, 0);
|
log_target_disas(pc_start, dc->pc - pc_start,
|
||||||
|
dc->env->pregs[PR_VR]);
|
||||||
qemu_log("\nisize=%d osize=%zd\n",
|
qemu_log("\nisize=%d osize=%zd\n",
|
||||||
dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
|
dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
|
||||||
}
|
}
|
||||||
|
@ -3390,6 +3449,39 @@ void cpu_dump_state (CPUState *env, FILE *f,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t vr;
|
||||||
|
const char *name;
|
||||||
|
} cris_cores[] = {
|
||||||
|
{8, "crisv8"},
|
||||||
|
{9, "crisv9"},
|
||||||
|
{10, "crisv10"},
|
||||||
|
{11, "crisv11"},
|
||||||
|
{32, "crisv32"},
|
||||||
|
};
|
||||||
|
|
||||||
|
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
(*cpu_fprintf)(f, "Available CPUs:\n");
|
||||||
|
for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
|
||||||
|
(*cpu_fprintf)(f, " %s\n", cris_cores[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t vr_by_name(const char *name)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
|
||||||
|
if (strcmp(name, cris_cores[i].name) == 0) {
|
||||||
|
return cris_cores[i].vr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
|
||||||
CPUCRISState *cpu_cris_init (const char *cpu_model)
|
CPUCRISState *cpu_cris_init (const char *cpu_model)
|
||||||
{
|
{
|
||||||
CPUCRISState *env;
|
CPUCRISState *env;
|
||||||
|
@ -3398,6 +3490,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
|
||||||
|
|
||||||
env = qemu_mallocz(sizeof(CPUCRISState));
|
env = qemu_mallocz(sizeof(CPUCRISState));
|
||||||
|
|
||||||
|
env->pregs[PR_VR] = vr_by_name(cpu_model);
|
||||||
cpu_exec_init(env);
|
cpu_exec_init(env);
|
||||||
cpu_reset(env);
|
cpu_reset(env);
|
||||||
qemu_init_vcpu(env);
|
qemu_init_vcpu(env);
|
||||||
|
@ -3407,6 +3500,15 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
|
||||||
|
|
||||||
tcg_initialized = 1;
|
tcg_initialized = 1;
|
||||||
|
|
||||||
|
#define GEN_HELPER 2
|
||||||
|
#include "helper.h"
|
||||||
|
|
||||||
|
if (env->pregs[PR_VR] < 32) {
|
||||||
|
cpu_crisv10_init(env);
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
|
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
|
||||||
cc_x = tcg_global_mem_new(TCG_AREG0,
|
cc_x = tcg_global_mem_new(TCG_AREG0,
|
||||||
offsetof(CPUState, cc_x), "cc_x");
|
offsetof(CPUState, cc_x), "cc_x");
|
||||||
|
@ -3447,26 +3549,26 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
|
||||||
pregnames[i]);
|
pregnames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GEN_HELPER 2
|
|
||||||
#include "helper.h"
|
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_reset (CPUCRISState *env)
|
void cpu_reset (CPUCRISState *env)
|
||||||
{
|
{
|
||||||
|
uint32_t vr;
|
||||||
|
|
||||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||||
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
||||||
log_cpu_state(env, 0);
|
log_cpu_state(env, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vr = env->pregs[PR_VR];
|
||||||
memset(env, 0, offsetof(CPUCRISState, breakpoints));
|
memset(env, 0, offsetof(CPUCRISState, breakpoints));
|
||||||
|
env->pregs[PR_VR] = vr;
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
|
|
||||||
env->pregs[PR_VR] = 32;
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
/* start in user mode with interrupts enabled. */
|
/* start in user mode with interrupts enabled. */
|
||||||
env->pregs[PR_CCS] |= U_FLAG | I_FLAG;
|
env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
|
||||||
#else
|
#else
|
||||||
cris_mmu_init(env);
|
cris_mmu_init(env);
|
||||||
env->pregs[PR_CCS] = 0;
|
env->pregs[PR_CCS] = 0;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue