Revision 40e9eddd

b/target-cris/cpu.h
262 262
				     | X_FLAG | PFIX_FLAG));
263 263
}
264 264

  
265
#define cpu_list cris_cpu_list
266
void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
267

  
265 268
#endif
b/target-cris/crisv10-decode.h
1
/*
2
 *  CRISv10 insn decoding macros.
3
 *
4
 *  Copyright (c) 2010 AXIS Communications AB
5
 *  Written by Edgar E. Iglesias.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20
 */
21

  
22
#define CRISV10_MODE_QIMMEDIATE  0
23
#define CRISV10_MODE_REG         1
24
#define CRISV10_MODE_INDIRECT    2
25
#define CRISV10_MODE_AUTOINC     3
26

  
27
/* Quick Immediate.  */
28
#define CRISV10_QIMM_BCC_R0      0
29
#define CRISV10_QIMM_BCC_R1      1
30
#define CRISV10_QIMM_BCC_R2      2
31
#define CRISV10_QIMM_BCC_R3      3
32

  
33
#define CRISV10_QIMM_BDAP_R0     4
34
#define CRISV10_QIMM_BDAP_R1     5
35
#define CRISV10_QIMM_BDAP_R2     6
36
#define CRISV10_QIMM_BDAP_R3     7
37

  
38
#define CRISV10_QIMM_ADDQ        8
39
#define CRISV10_QIMM_MOVEQ       9
40
#define CRISV10_QIMM_SUBQ       10
41
#define CRISV10_QIMM_CMPQ       11
42
#define CRISV10_QIMM_ANDQ       12
43
#define CRISV10_QIMM_ORQ        13
44
#define CRISV10_QIMM_ASHQ       14
45
#define CRISV10_QIMM_LSHQ       15
46

  
47

  
48
#define CRISV10_REG_ADDX         0
49
#define CRISV10_REG_MOVX         1
50
#define CRISV10_REG_SUBX         2
51
#define CRISV10_REG_LSL          3
52
#define CRISV10_REG_ADDI         4
53
#define CRISV10_REG_BIAP         5
54
#define CRISV10_REG_NEG          6
55
#define CRISV10_REG_BOUND        7
56
#define CRISV10_REG_ADD          8
57
#define CRISV10_REG_MOVE_R       9
58
#define CRISV10_REG_MOVE_SPR_R   9
59
#define CRISV10_REG_MOVE_R_SPR   8
60
#define CRISV10_REG_SUB         10
61
#define CRISV10_REG_CMP         11
62
#define CRISV10_REG_AND         12
63
#define CRISV10_REG_OR          13
64
#define CRISV10_REG_ASR         14
65
#define CRISV10_REG_LSR         15
66

  
67
#define CRISV10_REG_BTST         3
68
#define CRISV10_REG_SCC          4
69
#define CRISV10_REG_SETF         6
70
#define CRISV10_REG_CLEARF       7
71
#define CRISV10_REG_BIAP         5
72
#define CRISV10_REG_ABS         10
73
#define CRISV10_REG_DSTEP       11
74
#define CRISV10_REG_LZ          12
75
#define CRISV10_REG_NOT         13
76
#define CRISV10_REG_SWAP        13
77
#define CRISV10_REG_XOR         14
78
#define CRISV10_REG_MSTEP       15
79

  
80
/* Indirect, var size.  */
81
#define CRISV10_IND_TEST        14
82
#define CRISV10_IND_MUL          4
83
#define CRISV10_IND_BDAP_M       5
84
#define CRISV10_IND_ADD          8
85
#define CRISV10_IND_MOVE_M_R     9
86

  
87

  
88
/* indirect fixed size.  */
89
#define CRISV10_IND_ADDX         0
90
#define CRISV10_IND_MOVX         1
91
#define CRISV10_IND_SUBX         2
92
#define CRISV10_IND_CMPX         3
93
#define CRISV10_IND_JUMP_M       4
94
#define CRISV10_IND_DIP          5
95
#define CRISV10_IND_JUMP_R       6
96
#define CRISV10_IND_BOUND        7
97
#define CRISV10_IND_BCC_M        7
98
#define CRISV10_IND_MOVE_M_SPR   8
99
#define CRISV10_IND_MOVE_SPR_M   9
100
#define CRISV10_IND_SUB         10
101
#define CRISV10_IND_CMP         11
102
#define CRISV10_IND_AND         12
103
#define CRISV10_IND_OR          13
104
#define CRISV10_IND_MOVE_R_M    15
105

  
106
#define CRISV10_IND_MOVEM_M_R    14
107
#define CRISV10_IND_MOVEM_R_M    15
108

  
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;
b/target-cris/translate_v10.c
1
/*
2
 *  CRISv10 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2010 AXIS Communications AB
5
 *  Written by Edgar E. Iglesias.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20
 */
21

  
22
#include "crisv10-decode.h"
23

  
24
static const char *regnames_v10[] =
25
{
26
	"$r0", "$r1", "$r2", "$r3",
27
	"$r4", "$r5", "$r6", "$r7",
28
	"$r8", "$r9", "$r10", "$r11",
29
	"$r12", "$r13", "$sp", "$pc",
30
};
31

  
32
static const char *pregnames_v10[] =
33
{
34
	"$bz", "$vr", "$p2", "$p3",
35
	"$wz", "$ccr", "$p6-prefix", "$mof",
36
	"$dz", "$ibr", "$irp", "$srp",
37
	"$bar", "$dccr", "$brp", "$usp",
38
};
39

  
40
/* We need this table to handle preg-moves with implicit width.  */
41
static int preg_sizes_v10[] = {
42
	1, /* bz.  */
43
	1, /* vr.  */
44
	1, /* pid. */
45
	1, /* srs. */
46
	2, /* wz.  */
47
	2, 2, 4,
48
	4, 4, 4, 4,
49
	4, 4, 4, 4,
50
};
51

  
52
static inline int dec10_size(unsigned int size)
53
{
54
    size++;
55
    if (size == 3)
56
        size++;
57
    return size;
58
}
59

  
60
static inline void cris_illegal_insn(DisasContext *dc)
61
{
62
    qemu_log("illegal insn at pc=%x\n", dc->pc);
63
    t_gen_raise_exception(EXCP_BREAK);
64
}
65

  
66
/* Prefix flag and register are used to handle the more complex
67
   addressing modes.  */
68
static void cris_set_prefix(DisasContext *dc)
69
{
70
    dc->clear_prefix = 0;
71
    dc->tb_flags |= PFIX_FLAG;
72
    tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG);
73

  
74
    /* prefix insns dont clear the x flag.  */
75
    dc->clear_x = 0;
76
    cris_lock_irq(dc);
77
}
78

  
79
static void crisv10_prepare_memaddr(DisasContext *dc,
80
                                    TCGv addr, unsigned int size)
81
{
82
    if (dc->tb_flags & PFIX_FLAG) {
83
        tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]);
84
    } else {
85
        tcg_gen_mov_tl(addr, cpu_R[dc->src]);
86
    }
87
}
88

  
89
static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
90
{
91
    unsigned int insn_len = 0;
92

  
93
    if (dc->tb_flags & PFIX_FLAG) {
94
        if (dc->mode == CRISV10_MODE_AUTOINC) {
95
            tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]);
96
        }
97
    } else {
98
        if (dc->mode == CRISV10_MODE_AUTOINC) {
99
            if (dc->src == 15) {
100
                insn_len += size & ~1;
101
            } else {
102
                tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size);
103
            }
104
        }
105
    }
106
    return insn_len;
107
}
108

  
109
static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
110
                           TCGv dst)
111
{
112
        unsigned int rs, rd;
113
        uint32_t imm;
114
        int is_imm;
115
        int insn_len = 0;
116

  
117
        rs = dc->src;
118
        rd = dc->dst;
119
        is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG);
120
        LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n",
121
                  rs, rd, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG);
122

  
123
        /* Load [$rs] onto T1.  */
124
        if (is_imm) {
125
                if (memsize != 4) {
126
                        if (s_ext) {
127
                                if (memsize == 1)
128
                                        imm = ldsb_code(dc->pc + 2);
129
                                else
130
                                        imm = ldsw_code(dc->pc + 2);
131
                        } else {
132
                                if (memsize == 1)
133
                                        imm = ldub_code(dc->pc + 2);
134
                                else
135
                                        imm = lduw_code(dc->pc + 2);
136
                        }
137
                } else
138
                        imm = ldl_code(dc->pc + 2);
139

  
140
                tcg_gen_movi_tl(dst, imm);
141

  
142
                if (dc->mode == CRISV10_MODE_AUTOINC) {
143
                    insn_len += memsize;
144
                    if (memsize == 1)
145
                            insn_len++;
146
                    tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len);
147
                }
148
        } else {
149
                TCGv addr;
150

  
151
                addr = tcg_temp_new();
152
                cris_flush_cc_state(dc);
153
                crisv10_prepare_memaddr(dc, addr, memsize);
154
                gen_load(dc, dst, addr, memsize, 0);
155
                if (s_ext)
156
                        t_gen_sext(dst, dst, memsize);
157
                else
158
                        t_gen_zext(dst, dst, memsize);
159
                insn_len += crisv10_post_memaddr(dc, memsize);
160
                tcg_temp_free(addr);
161
        }
162

  
163
        if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) {
164
            dc->dst = dc->src;
165
        }
166
        return insn_len;
167
}
168

  
169
static unsigned int dec10_quick_imm(DisasContext *dc)
170
{
171
    int32_t imm, simm;
172
    int op;
173

  
174
    /* sign extend.  */
175
    imm = dc->ir & ((1 << 6) - 1);
176
    simm = (int8_t) (imm << 2);
177
    simm >>= 2;
178
    switch (dc->opcode) {
179
        case CRISV10_QIMM_BDAP_R0:
180
        case CRISV10_QIMM_BDAP_R1:
181
        case CRISV10_QIMM_BDAP_R2:
182
        case CRISV10_QIMM_BDAP_R3:
183
            simm = (int8_t)dc->ir;
184
            LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
185
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
186
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
187
            cris_set_prefix(dc);
188
            if (dc->dst == 15) {
189
                tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
190
            } else {
191
                tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
192
            }
193
            break;
194

  
195
        case CRISV10_QIMM_MOVEQ:
196
            LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);
197

  
198
            cris_cc_mask(dc, CC_MASK_NZVC);
199
            cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
200
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
201
            break;
202
        case CRISV10_QIMM_CMPQ:
203
            LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);
204

  
205
            cris_cc_mask(dc, CC_MASK_NZVC);
206
            cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
207
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
208
            break;
209
        case CRISV10_QIMM_ADDQ:
210
            LOG_DIS("addq %d, $r%d\n", imm, dc->dst);
211

  
212
            cris_cc_mask(dc, CC_MASK_NZVC);
213
            cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
214
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
215
            break;
216
        case CRISV10_QIMM_ANDQ:
217
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
218

  
219
            cris_cc_mask(dc, CC_MASK_NZVC);
220
            cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
221
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
222
            break;
223
        case CRISV10_QIMM_ASHQ:
224
            LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);
225

  
226
            cris_cc_mask(dc, CC_MASK_NZVC);
227
            op = imm & (1 << 5);
228
            imm &= 0x1f;
229
            if (op) {
230
                cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
231
                          cpu_R[dc->dst], tcg_const_tl(imm), 4);
232
            } else {
233
                /* BTST */
234
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
235
                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
236
                           tcg_const_tl(imm), cpu_PR[PR_CCS]);
237
            }
238
            break;
239
        case CRISV10_QIMM_LSHQ:
240
            LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);
241

  
242
            op = CC_OP_LSL;
243
            if (imm & (1 << 5)) {
244
                op = CC_OP_LSR; 
245
            }
246
            imm &= 0x1f;
247
            cris_cc_mask(dc, CC_MASK_NZVC);
248
            cris_alu(dc, op, cpu_R[dc->dst],
249
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
250
            break;
251
        case CRISV10_QIMM_SUBQ:
252
            LOG_DIS("subq %d, $r%d\n", imm, dc->dst);
253

  
254
            cris_cc_mask(dc, CC_MASK_NZVC);
255
            cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
256
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
257
            break;
258
        case CRISV10_QIMM_ORQ:
259
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
260

  
261
            cris_cc_mask(dc, CC_MASK_NZVC);
262
            cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
263
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
264
            break;
265

  
266
        case CRISV10_QIMM_BCC_R0:
267
            if (!dc->ir) {
268
                cpu_abort(dc->env, "opcode zero\n");
269
            }
270
        case CRISV10_QIMM_BCC_R1:
271
        case CRISV10_QIMM_BCC_R2:
272
        case CRISV10_QIMM_BCC_R3:
273
            imm = dc->ir & 0xff;
274
            /* bit 0 is a sign bit.  */
275
            if (imm & 1) {
276
                imm |= 0xffffff00;   /* sign extend.  */
277
                imm &= ~1;           /* get rid of the sign bit.  */
278
            }
279
            imm += 2;
280
            LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);
281

  
282
            cris_cc_mask(dc, 0);
283
            cris_prepare_cc_branch(dc, imm, dc->cond); 
284
            break;
285

  
286
        default:
287
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
288
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
289
            assert(0);
290
            break;
291
    }
292
    return 2;
293
}
294

  
295
static unsigned int dec10_setclrf(DisasContext *dc)
296
{
297
    uint32_t flags;
298
    unsigned int set = ~dc->opcode & 1;
299

  
300
    flags = EXTRACT_FIELD(dc->ir, 0, 3)
301
            | (EXTRACT_FIELD(dc->ir, 12, 15) << 4);
302
    LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags);
303

  
304

  
305
    if (flags & X_FLAG) {
306
        dc->flagx_known = 1;
307
        if (set)
308
            dc->flags_x = X_FLAG;
309
        else
310
            dc->flags_x = 0;
311
    }
312

  
313
    cris_evaluate_flags (dc);
314
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
315
    cris_update_cc_x(dc);
316
    tcg_gen_movi_tl(cc_op, dc->cc_op);
317

  
318
    if (set) {
319
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
320
    } else {
321
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
322
    }
323

  
324
    dc->flags_uptodate = 1;
325
    dc->clear_x = 0;
326
    cris_lock_irq(dc);
327
    return 2;
328
}
329

  
330
static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext,
331
				       TCGv dd, TCGv ds, TCGv sd, TCGv ss)
332
{
333
    if (sext) {
334
        t_gen_sext(dd, sd, size);
335
        t_gen_sext(ds, ss, size);
336
    } else {
337
        t_gen_zext(dd, sd, size);
338
        t_gen_zext(ds, ss, size);
339
    }
340
}
341

  
342
static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext)
343
{
344
    TCGv t[2];
345

  
346
    t[0] = tcg_temp_new();
347
    t[1] = tcg_temp_new();
348
    dec10_reg_prep_sext(dc, size, sext,
349
                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
350

  
351
    if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) {
352
        tcg_gen_andi_tl(t[1], t[1], 63);
353
    }
354

  
355
    assert(dc->dst != 15);
356
    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size);
357
    tcg_temp_free(t[0]);
358
    tcg_temp_free(t[1]);
359
}
360

  
361
static void dec10_reg_bound(DisasContext *dc, int size)
362
{
363
    TCGv t;
364

  
365
    t = tcg_temp_local_new();
366
    t_gen_zext(t, cpu_R[dc->src], size);
367
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
368
    tcg_temp_free(t);
369
}
370

  
371
static void dec10_reg_mul(DisasContext *dc, int size, int sext)
372
{
373
    int op = sext ? CC_OP_MULS : CC_OP_MULU;
374
    TCGv t[2];
375

  
376
    t[0] = tcg_temp_new();
377
    t[1] = tcg_temp_new();
378
    dec10_reg_prep_sext(dc, size, sext,
379
                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
380

  
381
    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4);
382

  
383
    tcg_temp_free(t[0]);
384
    tcg_temp_free(t[1]);
385
}
386

  
387

  
388
static void dec10_reg_movs(DisasContext *dc)
389
{
390
    int size = (dc->size & 1) + 1;
391
    TCGv t;
392

  
393
    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
394
    cris_cc_mask(dc, CC_MASK_NZVC);
395

  
396
    t = tcg_temp_new();
397
    if (dc->ir & 32)
398
        t_gen_sext(t, cpu_R[dc->src], size);
399
    else
400
        t_gen_zext(t, cpu_R[dc->src], size);
401

  
402
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
403
    tcg_temp_free(t);
404
}
405

  
406
static void dec10_reg_alux(DisasContext *dc, int op)
407
{
408
    int size = (dc->size & 1) + 1;
409
    TCGv t;
410

  
411
    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
412
    cris_cc_mask(dc, CC_MASK_NZVC);
413

  
414
    t = tcg_temp_new();
415
    if (dc->ir & 32)
416
        t_gen_sext(t, cpu_R[dc->src], size);
417
    else
418
        t_gen_zext(t, cpu_R[dc->src], size);
419

  
420
    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
421
    tcg_temp_free(t);
422
}
423

  
424
static void dec10_reg_mov_pr(DisasContext *dc)
425
{
426
    LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]);
427
    cris_lock_irq(dc);
428
    if (dc->src == 15) {
429
        tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]);
430
        cris_prepare_jmp(dc, JMP_INDIRECT);
431
        return;
432
    }
433
    if (dc->dst == PR_CCS) {
434
        cris_evaluate_flags(dc); 
435
    }
436
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src],
437
                 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]);
438
}
439

  
440
static void dec10_reg_abs(DisasContext *dc)
441
{
442
	TCGv t0;
443

  
444
	LOG_DIS("abs $r%u, $r%u\n",
445
		    dc->src, dc->dst);
446

  
447
	assert(dc->dst != 15);
448
	t0 = tcg_temp_new();
449
	tcg_gen_sari_tl(t0, cpu_R[dc->src], 31);
450
	tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0);
451
	tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0);
452

  
453
	cris_alu(dc, CC_OP_MOVE,
454
		    cpu_R[dc->dst], cpu_R[dc->dst], t0, 4);
455
	tcg_temp_free(t0);
456
}
457

  
458
static void dec10_reg_swap(DisasContext *dc)
459
{
460
    TCGv t0;
461

  
462
    LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst);
463

  
464
    cris_cc_mask(dc, CC_MASK_NZVC);
465
    t0 = tcg_temp_new();
466
    t_gen_mov_TN_reg(t0, dc->src);
467
    if (dc->dst & 8)
468
        tcg_gen_not_tl(t0, t0);
469
    if (dc->dst & 4)
470
        t_gen_swapw(t0, t0);
471
    if (dc->dst & 2)
472
        t_gen_swapb(t0, t0);
473
    if (dc->dst & 1)
474
        t_gen_swapr(t0, t0);
475
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4);
476
    tcg_temp_free(t0);
477
}
478

  
479
static void dec10_reg_scc(DisasContext *dc)
480
{
481
        int cond = dc->dst;
482

  
483
        LOG_DIS("s%s $r%u\n",
484
                    cc_name(cond), dc->src);
485

  
486
        if (cond != CC_A)
487
        {
488
                int l1;
489

  
490
                gen_tst_cc (dc, cpu_R[dc->src], cond);
491
                l1 = gen_new_label();
492
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1);
493
                tcg_gen_movi_tl(cpu_R[dc->src], 1);
494
                gen_set_label(l1);
495
        }
496
        else
497
                tcg_gen_movi_tl(cpu_R[dc->src], 1);
498

  
499
        cris_cc_mask(dc, 0);
500
}
501

  
502
static unsigned int dec10_reg(DisasContext *dc)
503
{
504
    TCGv t;
505
    unsigned int insn_len = 2;
506
    unsigned int size = dec10_size(dc->size);
507
    unsigned int tmp;
508

  
509
    if (dc->size != 3) {
510
        switch (dc->opcode) {
511
            case CRISV10_REG_MOVE_R:
512
                LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst);
513
                cris_cc_mask(dc, CC_MASK_NZVC);
514
                dec10_reg_alu(dc, CC_OP_MOVE, size, 0);
515
                if (dc->dst == 15) {
516
                    tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
517
                    cris_prepare_jmp(dc, JMP_INDIRECT);
518
                    dc->delayed_branch = 1;
519
                }
520
                break;
521
            case CRISV10_REG_MOVX:
522
                cris_cc_mask(dc, CC_MASK_NZVC);
523
                dec10_reg_movs(dc);
524
                break;
525
            case CRISV10_REG_ADDX:
526
                cris_cc_mask(dc, CC_MASK_NZVC);
527
                dec10_reg_alux(dc, CC_OP_ADD);
528
                break;
529
            case CRISV10_REG_SUBX:
530
                cris_cc_mask(dc, CC_MASK_NZVC);
531
                dec10_reg_alux(dc, CC_OP_SUB);
532
                break;
533
            case CRISV10_REG_ADD:
534
                LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
535
                cris_cc_mask(dc, CC_MASK_NZVC);
536
                dec10_reg_alu(dc, CC_OP_ADD, size, 0);
537
                break;
538
            case CRISV10_REG_SUB:
539
                LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
540
                cris_cc_mask(dc, CC_MASK_NZVC);
541
                dec10_reg_alu(dc, CC_OP_SUB, size, 0);
542
                break;
543
            case CRISV10_REG_CMP:
544
                LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
545
                cris_cc_mask(dc, CC_MASK_NZVC);
546
                dec10_reg_alu(dc, CC_OP_CMP, size, 0);
547
                break;
548
            case CRISV10_REG_BOUND:
549
                LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
550
                cris_cc_mask(dc, CC_MASK_NZVC);
551
                dec10_reg_bound(dc, size);
552
                break;
553
            case CRISV10_REG_AND:
554
                LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
555
                cris_cc_mask(dc, CC_MASK_NZVC);
556
                dec10_reg_alu(dc, CC_OP_AND, size, 0);
557
                break;
558
            case CRISV10_REG_ADDI:
559
                if (dc->src == 15) {
560
                    /* nop.  */
561
                    return 2;
562
                }
563
                t = tcg_temp_new();
564
                LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size);
565
                tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3);
566
                tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t);
567
                tcg_temp_free(t);
568
                break;
569
            case CRISV10_REG_LSL:
570
                LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
571
                cris_cc_mask(dc, CC_MASK_NZVC);
572
                dec10_reg_alu(dc, CC_OP_LSL, size, 0);
573
                break;
574
            case CRISV10_REG_LSR:
575
                LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
576
                cris_cc_mask(dc, CC_MASK_NZVC);
577
                dec10_reg_alu(dc, CC_OP_LSR, size, 0);
578
                break;
579
            case CRISV10_REG_ASR:
580
                LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
581
                cris_cc_mask(dc, CC_MASK_NZVC);
582
                dec10_reg_alu(dc, CC_OP_ASR, size, 1);
583
                break;
584
            case CRISV10_REG_OR:
585
                LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
586
                cris_cc_mask(dc, CC_MASK_NZVC);
587
                dec10_reg_alu(dc, CC_OP_OR, size, 0);
588
                break;
589
            case CRISV10_REG_NEG:
590
                LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
591
                cris_cc_mask(dc, CC_MASK_NZVC);
592
                dec10_reg_alu(dc, CC_OP_NEG, size, 0);
593
                break;
594
            case CRISV10_REG_BIAP:
595
                LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc,
596
                         dc->opcode, dc->src, dc->dst, size);
597
                switch (size) {
598
                    case 4: tmp = 2; break;
599
                    case 2: tmp = 1; break;
600
                    case 1: tmp = 0; break;
601
                    default: assert(0); break;
602
                }
603

  
604
                t = tcg_temp_new();
605
                tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp);
606
                if (dc->src == 15) {
607
                    tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1);
608
                } else {
609
                    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t);
610
                }
611
                tcg_temp_free(t);
612
                cris_set_prefix(dc);
613
                break;
614

  
615
            default:
616
                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
617
                         dc->opcode, dc->src, dc->dst);
618
                assert(0);
619
                break;
620
        }
621
    } else {
622
        switch (dc->opcode) {
623
            case CRISV10_REG_MOVX:
624
                cris_cc_mask(dc, CC_MASK_NZVC);
625
                dec10_reg_movs(dc);
626
                break;
627
            case CRISV10_REG_ADDX:
628
                cris_cc_mask(dc, CC_MASK_NZVC);
629
                dec10_reg_alux(dc, CC_OP_ADD);
630
                break;
631
            case CRISV10_REG_SUBX:
632
                cris_cc_mask(dc, CC_MASK_NZVC);
633
                dec10_reg_alux(dc, CC_OP_SUB);
634
                break;
635
            case CRISV10_REG_MOVE_SPR_R:
636
                cris_evaluate_flags(dc);
637
                cris_cc_mask(dc, 0);
638
                dec10_reg_mov_pr(dc);
639
                break;
640
            case CRISV10_REG_MOVE_R_SPR:
641
                LOG_DIS("move r%d p%d\n", dc->src, dc->dst);
642
                cris_evaluate_flags(dc);
643
                if (dc->src != 11) /* fast for srp.  */
644
                    dc->cpustate_changed = 1;
645
                t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]);
646
                break;
647
            case CRISV10_REG_SETF:
648
            case CRISV10_REG_CLEARF:
649
                dec10_setclrf(dc);
650
                break;
651
            case CRISV10_REG_SWAP:
652
                dec10_reg_swap(dc);
653
                break;
654
            case CRISV10_REG_ABS:
655
                cris_cc_mask(dc, CC_MASK_NZVC);
656
                dec10_reg_abs(dc);
657
                break;
658
            case CRISV10_REG_LZ:
659
                LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
660
                cris_cc_mask(dc, CC_MASK_NZVC);
661
                dec10_reg_alu(dc, CC_OP_LZ, 4, 0);
662
                break;
663
            case CRISV10_REG_XOR:
664
                LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
665
                cris_cc_mask(dc, CC_MASK_NZVC);
666
                dec10_reg_alu(dc, CC_OP_XOR, 4, 0);
667
                break;
668
            case CRISV10_REG_BTST:
669
                LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
670
                cris_cc_mask(dc, CC_MASK_NZVC);
671
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
672
                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
673
                           cpu_R[dc->src], cpu_PR[PR_CCS]);
674
                break;
675
            case CRISV10_REG_DSTEP:
676
                LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
677
                cris_cc_mask(dc, CC_MASK_NZVC);
678
                cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst],
679
                            cpu_R[dc->dst], cpu_R[dc->src], 4);
680
                break;
681
            case CRISV10_REG_MSTEP:
682
                LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
683
                cris_evaluate_flags(dc);
684
                cris_cc_mask(dc, CC_MASK_NZVC);
685
                cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst],
686
                            cpu_R[dc->dst], cpu_R[dc->src], 4);
687
                break;
688
            case CRISV10_REG_SCC:
689
                dec10_reg_scc(dc);
690
                break;
691
            default:
692
                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
693
                         dc->opcode, dc->src, dc->dst);
694
                assert(0);
695
                break;
696
        }
697
    }
698
    return insn_len;
699
}
700

  
701
static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
702
{
703
    unsigned int insn_len = 2;
704
    TCGv t;
705

  
706
    LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__,
707
             size, dc->src, dc->dst);
708

  
709
    cris_cc_mask(dc, CC_MASK_NZVC);
710
    t = tcg_temp_new();
711
    insn_len += dec10_prep_move_m(dc, 0, size, t);
712
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
713
    if (dc->dst == 15) {
714
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
715
        cris_prepare_jmp(dc, JMP_INDIRECT);
716
        dc->delayed_branch = 1;
717
        return insn_len;
718
    }
719

  
720
    tcg_temp_free(t);
721
    return insn_len;
722
}
723

  
724
static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
725
{
726
    unsigned int insn_len = 2;
727
    TCGv addr;
728

  
729
    LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
730
    addr = tcg_temp_new();
731
    crisv10_prepare_memaddr(dc, addr, size);
732
    gen_store(dc, addr, cpu_R[dc->dst], size);
733
    insn_len += crisv10_post_memaddr(dc, size);
734

  
735
    return insn_len;
736
}
737

  
738
static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
739
{
740
    unsigned int insn_len = 2, rd = dc->dst;
741
    TCGv t, addr;
742

  
743
    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
744
    cris_lock_irq(dc);
745

  
746
    addr = tcg_temp_new();
747
    t = tcg_temp_new();
748
    insn_len += dec10_prep_move_m(dc, 0, 4, t);
749
    if (rd == 15) {
750
        tcg_gen_mov_tl(env_btarget, t);
751
        cris_prepare_jmp(dc, JMP_INDIRECT);
752
        dc->delayed_branch = 1;
753
        return insn_len;
754
    }
755

  
756
    tcg_gen_mov_tl(cpu_PR[rd], t);
757
    dc->cpustate_changed = 1;
758
    tcg_temp_free(addr);
759
    tcg_temp_free(t);
760
    return insn_len;
761
}
762

  
763
static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
764
{
765
    unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst];
766
    TCGv addr, t0;
767

  
768
    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
769

  
770
    addr = tcg_temp_new();
771
    crisv10_prepare_memaddr(dc, addr, size);
772
    if (dc->dst == PR_CCS) {
773
        t0 = tcg_temp_new();
774
        cris_evaluate_flags(dc);
775
        tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
776
        gen_store(dc, addr, t0, size);
777
        tcg_temp_free(t0);
778
    } else {
779
        gen_store(dc, addr, cpu_PR[dc->dst], size);
780
    }
781
    t0 = tcg_temp_new();
782
    insn_len += crisv10_post_memaddr(dc, size);
783
    cris_lock_irq(dc);
784

  
785
    return insn_len;
786
}
787

  
788
static void dec10_movem_r_m(DisasContext *dc)
789
{
790
    int i, pfix = dc->tb_flags & PFIX_FLAG;
791
    TCGv addr, t0;
792

  
793
    LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__,
794
              dc->dst, dc->src, dc->postinc, dc->ir);
795

  
796
    addr = tcg_temp_new();
797
    t0 = tcg_temp_new();
798
    crisv10_prepare_memaddr(dc, addr, 4);
799
    tcg_gen_mov_tl(t0, addr);
800
    for (i = dc->dst; i >= 0; i--) {
801
        if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
802
            gen_store(dc, addr, t0, 4);
803
        } else {
804
            gen_store(dc, addr, cpu_R[i], 4);
805
        }
806
        tcg_gen_addi_tl(addr, addr, 4);
807
    }
808

  
809
    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
810
        tcg_gen_mov_tl(cpu_R[dc->src], t0);
811
    }
812

  
813
    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
814
        tcg_gen_mov_tl(cpu_R[dc->src], addr);
815
    }
816
    tcg_temp_free(addr);
817
    tcg_temp_free(t0);
818
}
819

  
820
static void dec10_movem_m_r(DisasContext *dc)
821
{
822
    int i, pfix = dc->tb_flags & PFIX_FLAG;
823
    TCGv addr, t0;
824

  
825
    LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__,
826
              dc->src, dc->dst, dc->postinc, dc->ir);
827

  
828
    addr = tcg_temp_new();
829
    t0 = tcg_temp_new();
830
    crisv10_prepare_memaddr(dc, addr, 4);
831
    tcg_gen_mov_tl(t0, addr);
832
    for (i = dc->dst; i >= 0; i--) {
833
        gen_load(dc, cpu_R[i], addr, 4, 0);
834
        tcg_gen_addi_tl(addr, addr, 4);
835
    }
836

  
837
    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
838
        tcg_gen_mov_tl(cpu_R[dc->src], t0);
839
    }
840

  
841

  
842
    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
843
        tcg_gen_mov_tl(cpu_R[dc->src], addr);
844
    }
845
    tcg_temp_free(addr);
846
    tcg_temp_free(t0);
847
}
848

  
849
static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
850
{
851
    int insn_len = 0;
852
    int rd = dc->dst;
853
    TCGv t[2];
854

  
855
    cris_alu_m_alloc_temps(t);
856
    insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
857
    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
858
    if (dc->dst == 15) {
859
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
860
        cris_prepare_jmp(dc, JMP_INDIRECT);
861
        dc->delayed_branch = 1;
862
        return insn_len;
863
    }
864

  
865
    cris_alu_m_free_temps(t);
866

  
867
    return insn_len;
868
}
869

  
870
static int dec10_ind_bound(DisasContext *dc, unsigned int size)
871
{
872
    int insn_len = 0;
873
    int rd = dc->dst;
874
    TCGv t;
875

  
876
    t = tcg_temp_local_new();
877
    insn_len += dec10_prep_move_m(dc, 0, size, t);
878
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
879
    if (dc->dst == 15) {
880
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
881
        cris_prepare_jmp(dc, JMP_INDIRECT);
882
        dc->delayed_branch = 1;
883
        return insn_len;
884
    }
885

  
886
    tcg_temp_free(t);
887
    return insn_len;
888
}
889

  
890
static int dec10_alux_m(DisasContext *dc, int op)
891
{
892
    unsigned int size = (dc->size & 1) ? 2 : 1;
893
    unsigned int sx = !!(dc->size & 2);
894
    int insn_len = 2;
895
    int rd = dc->dst;
896
    TCGv t;
897

  
898
    LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst);
899

  
900
    t = tcg_temp_new();
901

  
902
    cris_cc_mask(dc, CC_MASK_NZVC);
903
    insn_len += dec10_prep_move_m(dc, sx, size, t);
904
    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
905
    if (dc->dst == 15) {
906
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
907
        cris_prepare_jmp(dc, JMP_INDIRECT);
908
        dc->delayed_branch = 1;
909
        return insn_len;
910
    }
911

  
912
    tcg_temp_free(t);
913
    return insn_len;
914
}
915

  
916
static int dec10_dip(DisasContext *dc)
917
{
918
    int insn_len = 2;
919
    uint32_t imm;
920

  
921
    LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
922
              dc->pc, dc->opcode, dc->src, dc->dst);
923
    if (dc->src == 15) {
924
        imm = ldl_code(dc->pc + 2);
925
        tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
926
        if (dc->postinc)
927
            insn_len += 4;
928
        tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2);
929
    } else {
930
        gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0);
931
        if (dc->postinc)
932
            tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4);
933
    }
934

  
935
    cris_set_prefix(dc);
936
    return insn_len;
937
}
938

  
939
static int dec10_bdap_m(DisasContext *dc, int size)
940
{
941
    int insn_len = 2;
942
    int rd = dc->dst;
943

  
944
    LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n",
945
              dc->pc, dc->opcode, dc->src, dc->dst, size);
946

  
947
    assert(dc->dst != 15);
948
#if 0
949
    /* 8bit embedded offset?  */
950
    if (!dc->postinc && (dc->ir & (1 << 11))) {
951
        int simm = dc->ir & 0xff;
952

  
953
       // assert(0);
954
        /* sign extended.  */
955
        simm = (int8_t)simm;
956

  
957
        tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
958

  
959
        cris_set_prefix(dc);
960
        return insn_len;
961
    }
962
#endif
963
    /* Now the rest of the modes are truely indirect.  */
964
    insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]);
965
    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
966
    cris_set_prefix(dc);
967
    return insn_len;
968
}
969

  
970
static unsigned int dec10_ind(DisasContext *dc)
971
{
972
    unsigned int insn_len = 2;
973
    unsigned int size = dec10_size(dc->size);
974
    uint32_t imm;
975
    int32_t simm;
976
    TCGv t[2];
977

  
978
    if (dc->size != 3) {
979
        switch (dc->opcode) {
980
            case CRISV10_IND_MOVE_M_R:
981
                return dec10_ind_move_m_r(dc, size);
982
                break;
983
            case CRISV10_IND_MOVE_R_M:
984
                return dec10_ind_move_r_m(dc, size);
985
                break;
986
            case CRISV10_IND_CMP:
987
                LOG_DIS("cmp size=%d op=%d %d\n",  size, dc->src, dc->dst);
988
                cris_cc_mask(dc, CC_MASK_NZVC);
989
                insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
990
                break;
991
            case CRISV10_IND_TEST:
992
                LOG_DIS("test size=%d op=%d %d\n",  size, dc->src, dc->dst);
993

  
994
                cris_evaluate_flags(dc);
995
                cris_cc_mask(dc, CC_MASK_NZVC);
996
                cris_alu_m_alloc_temps(t);
997
                insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
998
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
999
                cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
1000
                         t[0], tcg_const_tl(0), size);
1001
                cris_alu_m_free_temps(t);
1002
                break;
1003
            case CRISV10_IND_ADD:
1004
                LOG_DIS("add size=%d op=%d %d\n",  size, dc->src, dc->dst);
1005
                cris_cc_mask(dc, CC_MASK_NZVC);
1006
                insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
1007
                break;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff