Revision 40e9eddd target-cris/translate.c

b/target-cris/translate.c
86 86
	target_ulong pc, ppc;
87 87

  
88 88
	/* Decoder.  */
89
	unsigned int (*decoder)(struct DisasContext *dc);
89 90
	uint32_t ir;
90 91
	uint32_t opcode;
91 92
	unsigned int op1;
......
94 95
	unsigned int mode;
95 96
	unsigned int postinc;
96 97

  
98
	unsigned int size;
99
	unsigned int src;
100
	unsigned int dst;
101
	unsigned int cond;
102

  
97 103
	int update_cc;
98 104
	int cc_op;
99 105
	int cc_size;
......
108 114
	int flags_x;
109 115

  
110 116
	int clear_x; /* Clear x after this insn?  */
117
	int clear_prefix; /* Clear prefix after this insn?  */
118
	int clear_locked_irq; /* Clear the irq lockout.  */
111 119
	int cpustate_changed;
112 120
	unsigned int tb_flags; /* tb dependent flags.  */
113 121
	int is_jmp;
......
219 227
	}
220 228
}
221 229

  
230
static void cris_lock_irq(DisasContext *dc)
231
{
232
	dc->clear_locked_irq = 0;
233
	t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
234
}
235

  
222 236
static inline void t_gen_raise_exception(uint32_t index)
223 237
{
224 238
        TCGv_i32 tmp = tcg_const_i32(index);
......
332 346
	gen_set_label(l1);
333 347
}
334 348

  
349
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
350
{
351
	TCGv t;
352

  
353
	/* 
354
	 * d <<= 1
355
	 * if (n)
356
	 *    d += s;
357
	 */
358
	t = tcg_temp_new();
359
	tcg_gen_shli_tl(d, a, 1);
360
	tcg_gen_shli_tl(t, ccs, 31 - 3);
361
	tcg_gen_sari_tl(t, t, 31);
362
	tcg_gen_and_tl(t, t, b);
363
	tcg_gen_add_tl(d, d, t);
364
	tcg_temp_free(t);
365
}
366

  
335 367
/* Extended arithmetics on CRIS.  */
336 368
static inline void t_gen_add_flag(TCGv d, int flag)
337 369
{
......
634 666
		if (dc->flags_x)
635 667
			tcg_gen_ori_tl(cpu_PR[PR_CCS], 
636 668
				       cpu_PR[PR_CCS], X_FLAG);
637
		else
669
		else if (dc->cc_op == CC_OP_FLAGS)
638 670
			tcg_gen_andi_tl(cpu_PR[PR_CCS], 
639 671
					cpu_PR[PR_CCS], ~X_FLAG);
640 672
        }
......
774 806
		case CC_OP_DSTEP:
775 807
			t_gen_cris_dstep(dst, a, b);
776 808
			break;
809
		case CC_OP_MSTEP:
810
			t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
811
			break;
777 812
		case CC_OP_BOUND:
778 813
		{
779 814
			int l1;
......
878 913
	move_opt = (dc->cc_op == CC_OP_MOVE);
879 914
	switch (cond) {
880 915
		case CC_EQ:
881
			if (arith_opt || move_opt) {
916
			if ((arith_opt || move_opt)
917
			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
882 918
				/* If cc_result is zero, T0 should be 
883 919
				   non-zero otherwise T0 should be zero.  */
884 920
				int l1;
......
896 932
			}
897 933
			break;
898 934
		case CC_NE:
899
			if (arith_opt || move_opt)
935
			if ((arith_opt || move_opt)
936
			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
900 937
				tcg_gen_mov_tl(cc, cc_result);
901
			else {
938
	 		} else {
902 939
				cris_evaluate_flags(dc);
903 940
				tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
904 941
						Z_FLAG);
......
2058 2095
			dc->flags_x = 0;
2059 2096
	}
2060 2097

  
2061
	/* Break the TB if the P flag changes.  */
2062
	if (flags & P_FLAG) {
2063
		if ((set && !(dc->tb_flags & P_FLAG))
2064
		    || (!set && (dc->tb_flags & P_FLAG))) {
2065
			tcg_gen_movi_tl(env_pc, dc->pc + 2);
2066
			dc->is_jmp = DISAS_UPDATE;
2067
			dc->cpustate_changed = 1;
2068
		}
2098
	/* Break the TB if any of the SPI flag changes.  */
2099
	if (flags & (P_FLAG | S_FLAG)) {
2100
		tcg_gen_movi_tl(env_pc, dc->pc + 2);
2101
		dc->is_jmp = DISAS_UPDATE;
2102
		dc->cpustate_changed = 1;
2069 2103
	}
2070
	if (flags & S_FLAG) {
2104

  
2105
	/* For the I flag, only act on posedge.  */
2106
	if ((flags & I_FLAG)) {
2107
		tcg_gen_movi_tl(env_pc, dc->pc + 2);
2108
		dc->is_jmp = DISAS_UPDATE;
2071 2109
		dc->cpustate_changed = 1;
2072 2110
	}
2073 2111

  
......
2143 2181
static unsigned int dec_move_pr(DisasContext *dc)
2144 2182
{
2145 2183
	TCGv t0;
2146
	LOG_DIS("move $p%u, $r%u\n", dc->op1, dc->op2);
2184
	LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2147 2185
	cris_cc_mask(dc, 0);
2148 2186

  
2149 2187
	if (dc->op2 == PR_CCS)
2150 2188
		cris_evaluate_flags(dc);
2151 2189

  
2152
	t0 = tcg_temp_new();
2153
	t_gen_mov_TN_preg(t0, dc->op2);
2154
	cris_alu(dc, CC_OP_MOVE,
2155
		 cpu_R[dc->op1], cpu_R[dc->op1], t0, preg_sizes[dc->op2]);
2156
	tcg_temp_free(t0);
2190
        if (dc->op2 == PR_DZ) {
2191
		tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2192
        } else {
2193
		t0 = tcg_temp_new();
2194
		t_gen_mov_TN_preg(t0, dc->op2);
2195
		cris_alu(dc, CC_OP_MOVE,
2196
			 cpu_R[dc->op1], cpu_R[dc->op1], t0,
2197
			 preg_sizes[dc->op2]);
2198
		tcg_temp_free(t0);
2199
	}
2157 2200
	return 2;
2158 2201
}
2159 2202

  
......
3026 3069
	{{0, 0}, dec_null}
3027 3070
};
3028 3071

  
3029
static inline unsigned int
3030
cris_decoder(DisasContext *dc)
3072
static unsigned int crisv32_decoder(DisasContext *dc)
3031 3073
{
3032 3074
	unsigned int insn_len = 2;
3033 3075
	int i;
......
3090 3132
	}
3091 3133
}
3092 3134

  
3135
#include "translate_v10.c"
3093 3136

  
3094 3137
/*
3095 3138
 * Delay slots on QEMU/CRIS.
......
3132 3175
{
3133 3176
	uint16_t *gen_opc_end;
3134 3177
   	uint32_t pc_start;
3135
	unsigned int insn_len;
3178
	unsigned int insn_len, orig_flags;
3136 3179
	int j, lj;
3137 3180
	struct DisasContext ctx;
3138 3181
	struct DisasContext *dc = &ctx;
......
3143 3186

  
3144 3187
	qemu_log_try_set_file(stderr);
3145 3188

  
3189
	if (env->pregs[PR_VR] == 32)
3190
		dc->decoder = crisv32_decoder;
3191
	else
3192
		dc->decoder = crisv10_decoder;
3193

  
3146 3194
	/* Odd PC indicates that branch is rexecuting due to exception in the
3147 3195
	 * delayslot, like in real hw.
3148 3196
	 */
......
3162 3210
	dc->cc_x_uptodate = 0;
3163 3211
	dc->cc_mask = 0;
3164 3212
	dc->update_cc = 0;
3213
	dc->clear_prefix = 0;
3214
	dc->clear_locked_irq = 1;
3165 3215

  
3166 3216
	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
3167 3217
	dc->cc_size_uptodate = -1;
3168 3218

  
3169 3219
	/* Decode TB flags.  */
3170
	dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
3220
	orig_flags = dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
3221
					| X_FLAG | PFIX_FLAG);
3171 3222
	dc->delayed_branch = !!(tb->flags & 7);
3172 3223
	if (dc->delayed_branch)
3173 3224
		dc->jmp = JMP_INDIRECT;
......
3233 3284
                    gen_io_start();
3234 3285
		dc->clear_x = 1;
3235 3286

  
3236
		insn_len = cris_decoder(dc);		
3287
		insn_len = dc->decoder(dc);
3237 3288
		dc->ppc = dc->pc;
3238 3289
		dc->pc += insn_len;
3239 3290
		if (dc->clear_x)
......
3271 3322
		 && (dc->pc < next_page_start)
3272 3323
                 && num_insns < max_insns);
3273 3324

  
3325
	if (dc->tb_flags != orig_flags) {
3326
		dc->cpustate_changed = 1;
3327
	}
3328

  
3329
	if (dc->clear_locked_irq)
3330
		t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
3331

  
3274 3332
	npc = dc->pc;
3275 3333
	if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
3276 3334
		npc = dc->jmp_pc;
......
3330 3388
#ifdef DEBUG_DISAS
3331 3389
#if !DISAS_CRIS
3332 3390
	if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
3333
		log_target_disas(pc_start, dc->pc - pc_start, 0);
3391
		log_target_disas(pc_start, dc->pc - pc_start,
3392
                                 dc->env->pregs[PR_VR]);
3334 3393
		qemu_log("\nisize=%d osize=%zd\n",
3335 3394
			dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3336 3395
	}
......
3390 3449

  
3391 3450
}
3392 3451

  
3452
struct
3453
{
3454
    uint32_t vr;
3455
    const char *name;
3456
} cris_cores[] = {
3457
	{8, "crisv8"},
3458
	{9, "crisv9"},
3459
	{10, "crisv10"},
3460
	{11, "crisv11"},
3461
	{32, "crisv32"},
3462
};
3463

  
3464
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
3465
{
3466
    unsigned int i;
3467

  
3468
    (*cpu_fprintf)(f, "Available CPUs:\n");
3469
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3470
        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
3471
    }
3472
}
3473

  
3474
static uint32_t vr_by_name(const char *name)
3475
{
3476
    unsigned int i;
3477
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
3478
        if (strcmp(name, cris_cores[i].name) == 0) {
3479
            return cris_cores[i].vr;
3480
        }
3481
    }
3482
    return 32;
3483
}
3484

  
3393 3485
CPUCRISState *cpu_cris_init (const char *cpu_model)
3394 3486
{
3395 3487
	CPUCRISState *env;
......
3398 3490

  
3399 3491
	env = qemu_mallocz(sizeof(CPUCRISState));
3400 3492

  
3493
	env->pregs[PR_VR] = vr_by_name(cpu_model);
3401 3494
	cpu_exec_init(env);
3402 3495
	cpu_reset(env);
3403 3496
	qemu_init_vcpu(env);
......
3407 3500

  
3408 3501
	tcg_initialized = 1;
3409 3502

  
3503
#define GEN_HELPER 2
3504
#include "helper.h"
3505

  
3506
	if (env->pregs[PR_VR] < 32) {
3507
		cpu_crisv10_init(env);
3508
		return env; 
3509
	}
3510

  
3511

  
3410 3512
	cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
3411 3513
	cc_x = tcg_global_mem_new(TCG_AREG0,
3412 3514
				  offsetof(CPUState, cc_x), "cc_x");
......
3447 3549
					       pregnames[i]);
3448 3550
	}
3449 3551

  
3450
#define GEN_HELPER 2
3451
#include "helper.h"
3452

  
3453 3552
	return env;
3454 3553
}
3455 3554

  
3456 3555
void cpu_reset (CPUCRISState *env)
3457 3556
{
3557
	uint32_t vr;
3558

  
3458 3559
	if (qemu_loglevel_mask(CPU_LOG_RESET)) {
3459 3560
		qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
3460 3561
		log_cpu_state(env, 0);
3461 3562
	}
3462 3563

  
3564
	vr = env->pregs[PR_VR];
3463 3565
	memset(env, 0, offsetof(CPUCRISState, breakpoints));
3566
	env->pregs[PR_VR] = vr;
3464 3567
	tlb_flush(env, 1);
3465 3568

  
3466
	env->pregs[PR_VR] = 32;
3467 3569
#if defined(CONFIG_USER_ONLY)
3468 3570
	/* start in user mode with interrupts enabled.  */
3469
	env->pregs[PR_CCS] |= U_FLAG | I_FLAG;
3571
	env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
3470 3572
#else
3471 3573
	cris_mmu_init(env);
3472 3574
	env->pregs[PR_CCS] = 0;

Also available in: Unified diff