1 /*
2  *  CRIS emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2008 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, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /*
22  * FIXME:
23  * The condition code translation is in need of attention.
24  */
25 
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <inttypes.h>
31 
32 #include "cpu.h"
33 #include "exec-all.h"
34 #include "disas.h"
35 #include "tcg-op.h"
36 #include "helper.h"
37 #include "mmu.h"
38 #include "crisv32-decode.h"
39 #include "qemu-common.h"
40 
41 #define GEN_HELPER 1
42 #include "helper.h"
43 
44 #define DISAS_CRIS 0
45 #if DISAS_CRIS
46 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
47 #else
48 #  define LOG_DIS(...) do { } while (0)
49 #endif
50 
51 #define D(x)
52 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
53 #define BUG_ON(x) ({if (x) BUG();})
54 
55 #define DISAS_SWI 5
56 
57 /* Used by the decoder.  */
58 #define EXTRACT_FIELD(src, start, end) \
59             (((src) >> start) & ((1 << (end - start + 1)) - 1))
60 
61 #define CC_MASK_NZ 0xc
62 #define CC_MASK_NZV 0xe
63 #define CC_MASK_NZVC 0xf
64 #define CC_MASK_RNZV 0x10e
65 
66 static TCGv_ptr cpu_env;
67 static TCGv cpu_R[16];
68 static TCGv cpu_PR[16];
69 static TCGv cc_x;
70 static TCGv cc_src;
71 static TCGv cc_dest;
72 static TCGv cc_result;
73 static TCGv cc_op;
74 static TCGv cc_size;
75 static TCGv cc_mask;
76 
77 static TCGv env_btaken;
78 static TCGv env_btarget;
79 static TCGv env_pc;
80 
81 #include "gen-icount.h"
82 
83 /* This is the state at translation time.  */
84 typedef struct DisasContext {
85 	CPUState *env;
86 	target_ulong pc, ppc;
87 
88 	/* Decoder.  */
89 	unsigned int (*decoder)(struct DisasContext *dc);
90 	uint32_t ir;
91 	uint32_t opcode;
92 	unsigned int op1;
93 	unsigned int op2;
94 	unsigned int zsize, zzsize;
95 	unsigned int mode;
96 	unsigned int postinc;
97 
98 	unsigned int size;
99 	unsigned int src;
100 	unsigned int dst;
101 	unsigned int cond;
102 
103 	int update_cc;
104 	int cc_op;
105 	int cc_size;
106 	uint32_t cc_mask;
107 
108 	int cc_size_uptodate; /* -1 invalid or last written value.  */
109 
110 	int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
111 	int flags_uptodate; /* Wether or not $ccs is uptodate.  */
112 	int flagx_known; /* Wether or not flags_x has the x flag known at
113 			    translation time.  */
114 	int flags_x;
115 
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.  */
119 	int cpustate_changed;
120 	unsigned int tb_flags; /* tb dependent flags.  */
121 	int is_jmp;
122 
123 #define JMP_NOJMP     0
124 #define JMP_DIRECT    1
125 #define JMP_DIRECT_CC 2
126 #define JMP_INDIRECT  3
127 	int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */
128 	uint32_t jmp_pc;
129 
130 	int delayed_branch;
131 
132 	struct TranslationBlock *tb;
133 	int singlestep_enabled;
134 } DisasContext;
135 
gen_BUG(DisasContext * dc,const char * file,int line)136 static void gen_BUG(DisasContext *dc, const char *file, int line)
137 {
138 	printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
139 	qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
140 	cpu_abort(dc->env, "%s:%d\n", file, line);
141 }
142 
143 static const char *regnames[] =
144 {
145 	"$r0", "$r1", "$r2", "$r3",
146 	"$r4", "$r5", "$r6", "$r7",
147 	"$r8", "$r9", "$r10", "$r11",
148 	"$r12", "$r13", "$sp", "$acr",
149 };
150 static const char *pregnames[] =
151 {
152 	"$bz", "$vr", "$pid", "$srs",
153 	"$wz", "$exs", "$eda", "$mof",
154 	"$dz", "$ebp", "$erp", "$srp",
155 	"$nrp", "$ccs", "$usp", "$spc",
156 };
157 
158 /* We need this table to handle preg-moves with implicit width.  */
159 static int preg_sizes[] = {
160 	1, /* bz.  */
161 	1, /* vr.  */
162 	4, /* pid.  */
163 	1, /* srs.  */
164 	2, /* wz.  */
165 	4, 4, 4,
166 	4, 4, 4, 4,
167 	4, 4, 4, 4,
168 };
169 
170 #define t_gen_mov_TN_env(tn, member) \
171  _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
172 #define t_gen_mov_env_TN(member, tn) \
173  _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
174 
t_gen_mov_TN_reg(TCGv tn,int r)175 static inline void t_gen_mov_TN_reg(TCGv tn, int r)
176 {
177 	if (r < 0 || r > 15)
178 		fprintf(stderr, "wrong register read $r%d\n", r);
179 	tcg_gen_mov_tl(tn, cpu_R[r]);
180 }
t_gen_mov_reg_TN(int r,TCGv tn)181 static inline void t_gen_mov_reg_TN(int r, TCGv tn)
182 {
183 	if (r < 0 || r > 15)
184 		fprintf(stderr, "wrong register write $r%d\n", r);
185 	tcg_gen_mov_tl(cpu_R[r], tn);
186 }
187 
_t_gen_mov_TN_env(TCGv tn,int offset)188 static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
189 {
190 	if (offset > sizeof (CPUState))
191 		fprintf(stderr, "wrong load from env from off=%d\n", offset);
192 	tcg_gen_ld_tl(tn, cpu_env, offset);
193 }
_t_gen_mov_env_TN(int offset,TCGv tn)194 static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
195 {
196 	if (offset > sizeof (CPUState))
197 		fprintf(stderr, "wrong store to env at off=%d\n", offset);
198 	tcg_gen_st_tl(tn, cpu_env, offset);
199 }
200 
t_gen_mov_TN_preg(TCGv tn,int r)201 static inline void t_gen_mov_TN_preg(TCGv tn, int r)
202 {
203 	if (r < 0 || r > 15)
204 		fprintf(stderr, "wrong register read $p%d\n", r);
205 	if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
206 		tcg_gen_mov_tl(tn, tcg_const_tl(0));
207 	else if (r == PR_VR)
208 		tcg_gen_mov_tl(tn, tcg_const_tl(32));
209 	else
210 		tcg_gen_mov_tl(tn, cpu_PR[r]);
211 }
t_gen_mov_preg_TN(DisasContext * dc,int r,TCGv tn)212 static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
213 {
214 	if (r < 0 || r > 15)
215 		fprintf(stderr, "wrong register write $p%d\n", r);
216 	if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
217 		return;
218 	else if (r == PR_SRS)
219 		tcg_gen_andi_tl(cpu_PR[r], tn, 3);
220 	else {
221 		if (r == PR_PID)
222 			gen_helper_tlb_flush_pid(tn);
223 		if (dc->tb_flags & S_FLAG && r == PR_SPC)
224 			gen_helper_spc_write(tn);
225 		else if (r == PR_CCS)
226 			dc->cpustate_changed = 1;
227 		tcg_gen_mov_tl(cpu_PR[r], tn);
228 	}
229 }
230 
231 /* Sign extend at translation time.  */
sign_extend(unsigned int val,unsigned int width)232 static int sign_extend(unsigned int val, unsigned int width)
233 {
234 	int sval;
235 
236 	/* LSL.  */
237 	val <<= 31 - width;
238 	sval = val;
239 	/* ASR.  */
240 	sval >>= 31 - width;
241 	return sval;
242 }
243 
cris_fetch(DisasContext * dc,uint32_t addr,unsigned int size,unsigned int sign)244 static int cris_fetch(DisasContext *dc, uint32_t addr,
245 		      unsigned int size, unsigned int sign)
246 {
247 	int r;
248 
249 	switch (size) {
250 		case 4:
251 		{
252 			r = ldl_code(addr);
253 			break;
254 		}
255 		case 2:
256 		{
257 			if (sign) {
258 				r = ldsw_code(addr);
259 			} else {
260 				r = lduw_code(addr);
261 			}
262 			break;
263 		}
264 		case 1:
265 		{
266 			if (sign) {
267 				r = ldsb_code(addr);
268 			} else {
269 				r = ldub_code(addr);
270 			}
271 			break;
272 		}
273 		default:
274 			cpu_abort(dc->env, "Invalid fetch size %d\n", size);
275 			break;
276 	}
277 	return r;
278 }
279 
cris_lock_irq(DisasContext * dc)280 static void cris_lock_irq(DisasContext *dc)
281 {
282 	dc->clear_locked_irq = 0;
283 	t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
284 }
285 
t_gen_raise_exception(uint32_t index)286 static inline void t_gen_raise_exception(uint32_t index)
287 {
288         TCGv_i32 tmp = tcg_const_i32(index);
289 	gen_helper_raise_exception(tmp);
290         tcg_temp_free_i32(tmp);
291 }
292 
t_gen_lsl(TCGv d,TCGv a,TCGv b)293 static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
294 {
295 	TCGv t0, t_31;
296 
297 	t0 = tcg_temp_new();
298 	t_31 = tcg_const_tl(31);
299 	tcg_gen_shl_tl(d, a, b);
300 
301 	tcg_gen_sub_tl(t0, t_31, b);
302 	tcg_gen_sar_tl(t0, t0, t_31);
303 	tcg_gen_and_tl(t0, t0, d);
304 	tcg_gen_xor_tl(d, d, t0);
305 	tcg_temp_free(t0);
306 	tcg_temp_free(t_31);
307 }
308 
t_gen_lsr(TCGv d,TCGv a,TCGv b)309 static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
310 {
311 	TCGv t0, t_31;
312 
313 	t0 = tcg_temp_new();
314 	t_31 = tcg_temp_new();
315 	tcg_gen_shr_tl(d, a, b);
316 
317 	tcg_gen_movi_tl(t_31, 31);
318 	tcg_gen_sub_tl(t0, t_31, b);
319 	tcg_gen_sar_tl(t0, t0, t_31);
320 	tcg_gen_and_tl(t0, t0, d);
321 	tcg_gen_xor_tl(d, d, t0);
322 	tcg_temp_free(t0);
323 	tcg_temp_free(t_31);
324 }
325 
t_gen_asr(TCGv d,TCGv a,TCGv b)326 static void t_gen_asr(TCGv d, TCGv a, TCGv b)
327 {
328 	TCGv t0, t_31;
329 
330 	t0 = tcg_temp_new();
331 	t_31 = tcg_temp_new();
332 	tcg_gen_sar_tl(d, a, b);
333 
334 	tcg_gen_movi_tl(t_31, 31);
335 	tcg_gen_sub_tl(t0, t_31, b);
336 	tcg_gen_sar_tl(t0, t0, t_31);
337 	tcg_gen_or_tl(d, d, t0);
338 	tcg_temp_free(t0);
339 	tcg_temp_free(t_31);
340 }
341 
342 /* 64-bit signed mul, lower result in d and upper in d2.  */
t_gen_muls(TCGv d,TCGv d2,TCGv a,TCGv b)343 static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
344 {
345 	TCGv_i64 t0, t1;
346 
347 	t0 = tcg_temp_new_i64();
348 	t1 = tcg_temp_new_i64();
349 
350 	tcg_gen_ext_i32_i64(t0, a);
351 	tcg_gen_ext_i32_i64(t1, b);
352 	tcg_gen_mul_i64(t0, t0, t1);
353 
354 	tcg_gen_trunc_i64_i32(d, t0);
355 	tcg_gen_shri_i64(t0, t0, 32);
356 	tcg_gen_trunc_i64_i32(d2, t0);
357 
358 	tcg_temp_free_i64(t0);
359 	tcg_temp_free_i64(t1);
360 }
361 
362 /* 64-bit unsigned muls, lower result in d and upper in d2.  */
t_gen_mulu(TCGv d,TCGv d2,TCGv a,TCGv b)363 static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
364 {
365 	TCGv_i64 t0, t1;
366 
367 	t0 = tcg_temp_new_i64();
368 	t1 = tcg_temp_new_i64();
369 
370 	tcg_gen_extu_i32_i64(t0, a);
371 	tcg_gen_extu_i32_i64(t1, b);
372 	tcg_gen_mul_i64(t0, t0, t1);
373 
374 	tcg_gen_trunc_i64_i32(d, t0);
375 	tcg_gen_shri_i64(t0, t0, 32);
376 	tcg_gen_trunc_i64_i32(d2, t0);
377 
378 	tcg_temp_free_i64(t0);
379 	tcg_temp_free_i64(t1);
380 }
381 
t_gen_cris_dstep(TCGv d,TCGv a,TCGv b)382 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
383 {
384 	int l1;
385 
386 	l1 = gen_new_label();
387 
388 	/*
389 	 * d <<= 1
390 	 * if (d >= s)
391 	 *    d -= s;
392 	 */
393 	tcg_gen_shli_tl(d, a, 1);
394 	tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
395 	tcg_gen_sub_tl(d, d, b);
396 	gen_set_label(l1);
397 }
398 
t_gen_cris_mstep(TCGv d,TCGv a,TCGv b,TCGv ccs)399 static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
400 {
401 	TCGv t;
402 
403 	/*
404 	 * d <<= 1
405 	 * if (n)
406 	 *    d += s;
407 	 */
408 	t = tcg_temp_new();
409 	tcg_gen_shli_tl(d, a, 1);
410 	tcg_gen_shli_tl(t, ccs, 31 - 3);
411 	tcg_gen_sari_tl(t, t, 31);
412 	tcg_gen_and_tl(t, t, b);
413 	tcg_gen_add_tl(d, d, t);
414 	tcg_temp_free(t);
415 }
416 
417 /* Extended arithmetics on CRIS.  */
t_gen_add_flag(TCGv d,int flag)418 static inline void t_gen_add_flag(TCGv d, int flag)
419 {
420 	TCGv c;
421 
422 	c = tcg_temp_new();
423 	t_gen_mov_TN_preg(c, PR_CCS);
424 	/* Propagate carry into d.  */
425 	tcg_gen_andi_tl(c, c, 1 << flag);
426 	if (flag)
427 		tcg_gen_shri_tl(c, c, flag);
428 	tcg_gen_add_tl(d, d, c);
429 	tcg_temp_free(c);
430 }
431 
t_gen_addx_carry(DisasContext * dc,TCGv d)432 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
433 {
434 	if (dc->flagx_known) {
435 		if (dc->flags_x) {
436 			TCGv c;
437 
438 			c = tcg_temp_new();
439 			t_gen_mov_TN_preg(c, PR_CCS);
440 			/* C flag is already at bit 0.  */
441 			tcg_gen_andi_tl(c, c, C_FLAG);
442 			tcg_gen_add_tl(d, d, c);
443 			tcg_temp_free(c);
444 		}
445 	} else {
446 		TCGv x, c;
447 
448 		x = tcg_temp_new();
449 		c = tcg_temp_new();
450 		t_gen_mov_TN_preg(x, PR_CCS);
451 		tcg_gen_mov_tl(c, x);
452 
453 		/* Propagate carry into d if X is set. Branch free.  */
454 		tcg_gen_andi_tl(c, c, C_FLAG);
455 		tcg_gen_andi_tl(x, x, X_FLAG);
456 		tcg_gen_shri_tl(x, x, 4);
457 
458 		tcg_gen_and_tl(x, x, c);
459 		tcg_gen_add_tl(d, d, x);
460 		tcg_temp_free(x);
461 		tcg_temp_free(c);
462 	}
463 }
464 
t_gen_subx_carry(DisasContext * dc,TCGv d)465 static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
466 {
467 	if (dc->flagx_known) {
468 		if (dc->flags_x) {
469 			TCGv c;
470 
471 			c = tcg_temp_new();
472 			t_gen_mov_TN_preg(c, PR_CCS);
473 			/* C flag is already at bit 0.  */
474 			tcg_gen_andi_tl(c, c, C_FLAG);
475 			tcg_gen_sub_tl(d, d, c);
476 			tcg_temp_free(c);
477 		}
478 	} else {
479 		TCGv x, c;
480 
481 		x = tcg_temp_new();
482 		c = tcg_temp_new();
483 		t_gen_mov_TN_preg(x, PR_CCS);
484 		tcg_gen_mov_tl(c, x);
485 
486 		/* Propagate carry into d if X is set. Branch free.  */
487 		tcg_gen_andi_tl(c, c, C_FLAG);
488 		tcg_gen_andi_tl(x, x, X_FLAG);
489 		tcg_gen_shri_tl(x, x, 4);
490 
491 		tcg_gen_and_tl(x, x, c);
492 		tcg_gen_sub_tl(d, d, x);
493 		tcg_temp_free(x);
494 		tcg_temp_free(c);
495 	}
496 }
497 
498 /* Swap the two bytes within each half word of the s operand.
499    T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
t_gen_swapb(TCGv d,TCGv s)500 static inline void t_gen_swapb(TCGv d, TCGv s)
501 {
502 	TCGv t, org_s;
503 
504 	t = tcg_temp_new();
505 	org_s = tcg_temp_new();
506 
507 	/* d and s may refer to the same object.  */
508 	tcg_gen_mov_tl(org_s, s);
509 	tcg_gen_shli_tl(t, org_s, 8);
510 	tcg_gen_andi_tl(d, t, 0xff00ff00);
511 	tcg_gen_shri_tl(t, org_s, 8);
512 	tcg_gen_andi_tl(t, t, 0x00ff00ff);
513 	tcg_gen_or_tl(d, d, t);
514 	tcg_temp_free(t);
515 	tcg_temp_free(org_s);
516 }
517 
518 /* Swap the halfwords of the s operand.  */
t_gen_swapw(TCGv d,TCGv s)519 static inline void t_gen_swapw(TCGv d, TCGv s)
520 {
521 	TCGv t;
522 	/* d and s refer the same object.  */
523 	t = tcg_temp_new();
524 	tcg_gen_mov_tl(t, s);
525 	tcg_gen_shli_tl(d, t, 16);
526 	tcg_gen_shri_tl(t, t, 16);
527 	tcg_gen_or_tl(d, d, t);
528 	tcg_temp_free(t);
529 }
530 
531 /* Reverse the within each byte.
532    T0 = (((T0 << 7) & 0x80808080) |
533    ((T0 << 5) & 0x40404040) |
534    ((T0 << 3) & 0x20202020) |
535    ((T0 << 1) & 0x10101010) |
536    ((T0 >> 1) & 0x08080808) |
537    ((T0 >> 3) & 0x04040404) |
538    ((T0 >> 5) & 0x02020202) |
539    ((T0 >> 7) & 0x01010101));
540  */
t_gen_swapr(TCGv d,TCGv s)541 static inline void t_gen_swapr(TCGv d, TCGv s)
542 {
543 	struct {
544 		int shift; /* LSL when positive, LSR when negative.  */
545 		uint32_t mask;
546 	} bitrev [] = {
547 		{7, 0x80808080},
548 		{5, 0x40404040},
549 		{3, 0x20202020},
550 		{1, 0x10101010},
551 		{-1, 0x08080808},
552 		{-3, 0x04040404},
553 		{-5, 0x02020202},
554 		{-7, 0x01010101}
555 	};
556 	int i;
557 	TCGv t, org_s;
558 
559 	/* d and s refer the same object.  */
560 	t = tcg_temp_new();
561 	org_s = tcg_temp_new();
562 	tcg_gen_mov_tl(org_s, s);
563 
564 	tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
565 	tcg_gen_andi_tl(d, t,  bitrev[0].mask);
566 	for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
567 		if (bitrev[i].shift >= 0) {
568 			tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
569 		} else {
570 			tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
571 		}
572 		tcg_gen_andi_tl(t, t,  bitrev[i].mask);
573 		tcg_gen_or_tl(d, d, t);
574 	}
575 	tcg_temp_free(t);
576 	tcg_temp_free(org_s);
577 }
578 
t_gen_cc_jmp(TCGv pc_true,TCGv pc_false)579 static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
580 {
581 	int l1;
582 
583 	l1 = gen_new_label();
584 
585 	/* Conditional jmp.  */
586 	tcg_gen_mov_tl(env_pc, pc_false);
587 	tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
588 	tcg_gen_mov_tl(env_pc, pc_true);
589 	gen_set_label(l1);
590 }
591 
gen_goto_tb(DisasContext * dc,int n,target_ulong dest)592 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
593 {
594 	TranslationBlock *tb;
595 	tb = dc->tb;
596 	if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
597 		tcg_gen_goto_tb(n);
598 		tcg_gen_movi_tl(env_pc, dest);
599 		tcg_gen_exit_tb((long)tb + n);
600 	} else {
601 		tcg_gen_movi_tl(env_pc, dest);
602 		tcg_gen_exit_tb(0);
603 	}
604 }
605 
cris_clear_x_flag(DisasContext * dc)606 static inline void cris_clear_x_flag(DisasContext *dc)
607 {
608 	if (dc->flagx_known && dc->flags_x)
609 		dc->flags_uptodate = 0;
610 
611 	dc->flagx_known = 1;
612 	dc->flags_x = 0;
613 }
614 
cris_flush_cc_state(DisasContext * dc)615 static void cris_flush_cc_state(DisasContext *dc)
616 {
617 	if (dc->cc_size_uptodate != dc->cc_size) {
618 		tcg_gen_movi_tl(cc_size, dc->cc_size);
619 		dc->cc_size_uptodate = dc->cc_size;
620 	}
621 	tcg_gen_movi_tl(cc_op, dc->cc_op);
622 	tcg_gen_movi_tl(cc_mask, dc->cc_mask);
623 }
624 
cris_evaluate_flags(DisasContext * dc)625 static void cris_evaluate_flags(DisasContext *dc)
626 {
627 	if (dc->flags_uptodate)
628 		return;
629 
630 	cris_flush_cc_state(dc);
631 
632 	switch (dc->cc_op)
633 	{
634 	case CC_OP_MCP:
635 		gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
636 					cpu_PR[PR_CCS], cc_src,
637 					cc_dest, cc_result);
638 		break;
639 	case CC_OP_MULS:
640 		gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
641 					cpu_PR[PR_CCS], cc_result,
642 					cpu_PR[PR_MOF]);
643 		break;
644 	case CC_OP_MULU:
645 		gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
646 					cpu_PR[PR_CCS], cc_result,
647 					cpu_PR[PR_MOF]);
648 		break;
649 	case CC_OP_MOVE:
650 	case CC_OP_AND:
651 	case CC_OP_OR:
652 	case CC_OP_XOR:
653 	case CC_OP_ASR:
654 	case CC_OP_LSR:
655 	case CC_OP_LSL:
656 		switch (dc->cc_size)
657 		{
658 		case 4:
659 			gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
660 						cpu_PR[PR_CCS], cc_result);
661 			break;
662 		case 2:
663 			gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
664 						cpu_PR[PR_CCS], cc_result);
665 			break;
666 		default:
667 			gen_helper_evaluate_flags();
668 			break;
669 		}
670 		break;
671 	case CC_OP_FLAGS:
672 		/* live.  */
673 		break;
674 	case CC_OP_SUB:
675 	case CC_OP_CMP:
676 		if (dc->cc_size == 4)
677 			gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
678 				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
679 		else
680 			gen_helper_evaluate_flags();
681 
682 		break;
683 	default:
684 		switch (dc->cc_size)
685 		{
686 			case 4:
687 			gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
688 				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
689 				break;
690 			default:
691 				gen_helper_evaluate_flags();
692 				break;
693 		}
694 		break;
695 	}
696 
697 	if (dc->flagx_known) {
698 		if (dc->flags_x)
699 			tcg_gen_ori_tl(cpu_PR[PR_CCS],
700 				       cpu_PR[PR_CCS], X_FLAG);
701 		else if (dc->cc_op == CC_OP_FLAGS)
702 			tcg_gen_andi_tl(cpu_PR[PR_CCS],
703 					cpu_PR[PR_CCS], ~X_FLAG);
704         }
705 	dc->flags_uptodate = 1;
706 }
707 
cris_cc_mask(DisasContext * dc,unsigned int mask)708 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
709 {
710 	uint32_t ovl;
711 
712 	if (!mask) {
713 		dc->update_cc = 0;
714 		return;
715 	}
716 
717 	/* Check if we need to evaluate the condition codes due to
718 	   CC overlaying.  */
719 	ovl = (dc->cc_mask ^ mask) & ~mask;
720 	if (ovl) {
721 		/* TODO: optimize this case. It trigs all the time.  */
722 		cris_evaluate_flags (dc);
723 	}
724 	dc->cc_mask = mask;
725 	dc->update_cc = 1;
726 }
727 
cris_update_cc_op(DisasContext * dc,int op,int size)728 static void cris_update_cc_op(DisasContext *dc, int op, int size)
729 {
730 	dc->cc_op = op;
731 	dc->cc_size = size;
732 	dc->flags_uptodate = 0;
733 }
734 
cris_update_cc_x(DisasContext * dc)735 static inline void cris_update_cc_x(DisasContext *dc)
736 {
737 	/* Save the x flag state at the time of the cc snapshot.  */
738 	if (dc->flagx_known) {
739 		if (dc->cc_x_uptodate == (2 | dc->flags_x))
740 			return;
741 		tcg_gen_movi_tl(cc_x, dc->flags_x);
742 		dc->cc_x_uptodate = 2 | dc->flags_x;
743 	}
744 	else {
745 		tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
746 		dc->cc_x_uptodate = 1;
747 	}
748 }
749 
750 /* Update cc prior to executing ALU op. Needs source operands untouched.  */
cris_pre_alu_update_cc(DisasContext * dc,int op,TCGv dst,TCGv src,int size)751 static void cris_pre_alu_update_cc(DisasContext *dc, int op,
752 				   TCGv dst, TCGv src, int size)
753 {
754 	if (dc->update_cc) {
755 		cris_update_cc_op(dc, op, size);
756 		tcg_gen_mov_tl(cc_src, src);
757 
758 		if (op != CC_OP_MOVE
759 		    && op != CC_OP_AND
760 		    && op != CC_OP_OR
761 		    && op != CC_OP_XOR
762 		    && op != CC_OP_ASR
763 		    && op != CC_OP_LSR
764 		    && op != CC_OP_LSL)
765 			tcg_gen_mov_tl(cc_dest, dst);
766 
767 		cris_update_cc_x(dc);
768 	}
769 }
770 
771 /* Update cc after executing ALU op. needs the result.  */
cris_update_result(DisasContext * dc,TCGv res)772 static inline void cris_update_result(DisasContext *dc, TCGv res)
773 {
774 	if (dc->update_cc)
775 		tcg_gen_mov_tl(cc_result, res);
776 }
777 
778 /* Returns one if the write back stage should execute.  */
cris_alu_op_exec(DisasContext * dc,int op,TCGv dst,TCGv a,TCGv b,int size)779 static void cris_alu_op_exec(DisasContext *dc, int op,
780 			       TCGv dst, TCGv a, TCGv b, int size)
781 {
782 	/* Emit the ALU insns.  */
783 	switch (op)
784 	{
785 		case CC_OP_ADD:
786 			tcg_gen_add_tl(dst, a, b);
787 			/* Extended arithmetics.  */
788 			t_gen_addx_carry(dc, dst);
789 			break;
790 		case CC_OP_ADDC:
791 			tcg_gen_add_tl(dst, a, b);
792 			t_gen_add_flag(dst, 0); /* C_FLAG.  */
793 			break;
794 		case CC_OP_MCP:
795 			tcg_gen_add_tl(dst, a, b);
796 			t_gen_add_flag(dst, 8); /* R_FLAG.  */
797 			break;
798 		case CC_OP_SUB:
799 			tcg_gen_sub_tl(dst, a, b);
800 			/* Extended arithmetics.  */
801 			t_gen_subx_carry(dc, dst);
802 			break;
803 		case CC_OP_MOVE:
804 			tcg_gen_mov_tl(dst, b);
805 			break;
806 		case CC_OP_OR:
807 			tcg_gen_or_tl(dst, a, b);
808 			break;
809 		case CC_OP_AND:
810 			tcg_gen_and_tl(dst, a, b);
811 			break;
812 		case CC_OP_XOR:
813 			tcg_gen_xor_tl(dst, a, b);
814 			break;
815 		case CC_OP_LSL:
816 			t_gen_lsl(dst, a, b);
817 			break;
818 		case CC_OP_LSR:
819 			t_gen_lsr(dst, a, b);
820 			break;
821 		case CC_OP_ASR:
822 			t_gen_asr(dst, a, b);
823 			break;
824 		case CC_OP_NEG:
825 			tcg_gen_neg_tl(dst, b);
826 			/* Extended arithmetics.  */
827 			t_gen_subx_carry(dc, dst);
828 			break;
829 		case CC_OP_LZ:
830 			gen_helper_lz(dst, b);
831 			break;
832 		case CC_OP_MULS:
833 			t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
834 			break;
835 		case CC_OP_MULU:
836 			t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
837 			break;
838 		case CC_OP_DSTEP:
839 			t_gen_cris_dstep(dst, a, b);
840 			break;
841 		case CC_OP_MSTEP:
842 			t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
843 			break;
844 		case CC_OP_BOUND:
845 		{
846 			int l1;
847 			l1 = gen_new_label();
848 			tcg_gen_mov_tl(dst, a);
849 			tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
850 			tcg_gen_mov_tl(dst, b);
851 			gen_set_label(l1);
852 		}
853 		break;
854 		case CC_OP_CMP:
855 			tcg_gen_sub_tl(dst, a, b);
856 			/* Extended arithmetics.  */
857 			t_gen_subx_carry(dc, dst);
858 			break;
859 		default:
860 			qemu_log("illegal ALU op.\n");
861 			BUG();
862 			break;
863 	}
864 
865 	if (size == 1)
866 		tcg_gen_andi_tl(dst, dst, 0xff);
867 	else if (size == 2)
868 		tcg_gen_andi_tl(dst, dst, 0xffff);
869 }
870 
cris_alu(DisasContext * dc,int op,TCGv d,TCGv op_a,TCGv op_b,int size)871 static void cris_alu(DisasContext *dc, int op,
872 			       TCGv d, TCGv op_a, TCGv op_b, int size)
873 {
874 	TCGv tmp;
875 	int writeback;
876 
877 	writeback = 1;
878 
879 	if (op == CC_OP_CMP) {
880 		tmp = tcg_temp_new();
881 		writeback = 0;
882 	} else if (size == 4) {
883 		tmp = d;
884 		writeback = 0;
885 	} else
886 		tmp = tcg_temp_new();
887 
888 
889 	cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
890 	cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
891 	cris_update_result(dc, tmp);
892 
893 	/* Writeback.  */
894 	if (writeback) {
895 		if (size == 1)
896 			tcg_gen_andi_tl(d, d, ~0xff);
897 		else
898 			tcg_gen_andi_tl(d, d, ~0xffff);
899 		tcg_gen_or_tl(d, d, tmp);
900 	}
901 	if (!TCGV_EQUAL(tmp, d))
902 		tcg_temp_free(tmp);
903 }
904 
arith_cc(DisasContext * dc)905 static int arith_cc(DisasContext *dc)
906 {
907 	if (dc->update_cc) {
908 		switch (dc->cc_op) {
909 			case CC_OP_ADDC: return 1;
910 			case CC_OP_ADD: return 1;
911 			case CC_OP_SUB: return 1;
912 			case CC_OP_DSTEP: return 1;
913 			case CC_OP_LSL: return 1;
914 			case CC_OP_LSR: return 1;
915 			case CC_OP_ASR: return 1;
916 			case CC_OP_CMP: return 1;
917 			case CC_OP_NEG: return 1;
918 			case CC_OP_OR: return 1;
919 			case CC_OP_AND: return 1;
920 			case CC_OP_XOR: return 1;
921 			case CC_OP_MULU: return 1;
922 			case CC_OP_MULS: return 1;
923 			default:
924 				return 0;
925 		}
926 	}
927 	return 0;
928 }
929 
gen_tst_cc(DisasContext * dc,TCGv cc,int cond)930 static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
931 {
932 	int arith_opt, move_opt;
933 
934 	/* TODO: optimize more condition codes.  */
935 
936 	/*
937 	 * If the flags are live, we've gotta look into the bits of CCS.
938 	 * Otherwise, if we just did an arithmetic operation we try to
939 	 * evaluate the condition code faster.
940 	 *
941 	 * When this function is done, T0 should be non-zero if the condition
942 	 * code is true.
943 	 */
944 	arith_opt = arith_cc(dc) && !dc->flags_uptodate;
945 	move_opt = (dc->cc_op == CC_OP_MOVE);
946 	switch (cond) {
947 		case CC_EQ:
948 			if ((arith_opt || move_opt)
949 			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
950 				tcg_gen_setcond_tl(TCG_COND_EQ, cc,
951 						   cc_result, tcg_const_tl(0));
952 			}
953 			else {
954 				cris_evaluate_flags(dc);
955 				tcg_gen_andi_tl(cc,
956 						cpu_PR[PR_CCS], Z_FLAG);
957 			}
958 			break;
959 		case CC_NE:
960 			if ((arith_opt || move_opt)
961 			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
962 				tcg_gen_mov_tl(cc, cc_result);
963 	 		} else {
964 				cris_evaluate_flags(dc);
965 				tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
966 						Z_FLAG);
967 				tcg_gen_andi_tl(cc, cc, Z_FLAG);
968 			}
969 			break;
970 		case CC_CS:
971 			cris_evaluate_flags(dc);
972 			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
973 			break;
974 		case CC_CC:
975 			cris_evaluate_flags(dc);
976 			tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
977 			tcg_gen_andi_tl(cc, cc, C_FLAG);
978 			break;
979 		case CC_VS:
980 			cris_evaluate_flags(dc);
981 			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
982 			break;
983 		case CC_VC:
984 			cris_evaluate_flags(dc);
985 			tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
986 					V_FLAG);
987 			tcg_gen_andi_tl(cc, cc, V_FLAG);
988 			break;
989 		case CC_PL:
990 			if (arith_opt || move_opt) {
991 				int bits = 31;
992 
993 				if (dc->cc_size == 1)
994 					bits = 7;
995 				else if (dc->cc_size == 2)
996 					bits = 15;
997 
998 				tcg_gen_shri_tl(cc, cc_result, bits);
999 				tcg_gen_xori_tl(cc, cc, 1);
1000 			} else {
1001 				cris_evaluate_flags(dc);
1002 				tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
1003 						N_FLAG);
1004 				tcg_gen_andi_tl(cc, cc, N_FLAG);
1005 			}
1006 			break;
1007 		case CC_MI:
1008 			if (arith_opt || move_opt) {
1009 				int bits = 31;
1010 
1011 				if (dc->cc_size == 1)
1012 					bits = 7;
1013 				else if (dc->cc_size == 2)
1014 					bits = 15;
1015 
1016 				tcg_gen_shri_tl(cc, cc_result, bits);
1017 				tcg_gen_andi_tl(cc, cc, 1);
1018 			}
1019 			else {
1020 				cris_evaluate_flags(dc);
1021 				tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1022 						N_FLAG);
1023 			}
1024 			break;
1025 		case CC_LS:
1026 			cris_evaluate_flags(dc);
1027 			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
1028 					C_FLAG | Z_FLAG);
1029 			break;
1030 		case CC_HI:
1031 			cris_evaluate_flags(dc);
1032 			{
1033 				TCGv tmp;
1034 
1035 				tmp = tcg_temp_new();
1036 				tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
1037 						C_FLAG | Z_FLAG);
1038 				/* Overlay the C flag on top of the Z.  */
1039 				tcg_gen_shli_tl(cc, tmp, 2);
1040 				tcg_gen_and_tl(cc, tmp, cc);
1041 				tcg_gen_andi_tl(cc, cc, Z_FLAG);
1042 
1043 				tcg_temp_free(tmp);
1044 			}
1045 			break;
1046 		case CC_GE:
1047 			cris_evaluate_flags(dc);
1048 			/* Overlay the V flag on top of the N.  */
1049 			tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1050 			tcg_gen_xor_tl(cc,
1051 				       cpu_PR[PR_CCS], cc);
1052 			tcg_gen_andi_tl(cc, cc, N_FLAG);
1053 			tcg_gen_xori_tl(cc, cc, N_FLAG);
1054 			break;
1055 		case CC_LT:
1056 			cris_evaluate_flags(dc);
1057 			/* Overlay the V flag on top of the N.  */
1058 			tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
1059 			tcg_gen_xor_tl(cc,
1060 				       cpu_PR[PR_CCS], cc);
1061 			tcg_gen_andi_tl(cc, cc, N_FLAG);
1062 			break;
1063 		case CC_GT:
1064 			cris_evaluate_flags(dc);
1065 			{
1066 				TCGv n, z;
1067 
1068 				n = tcg_temp_new();
1069 				z = tcg_temp_new();
1070 
1071 				/* To avoid a shift we overlay everything on
1072 				   the V flag.  */
1073 				tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1074 				tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1075 				/* invert Z.  */
1076 				tcg_gen_xori_tl(z, z, 2);
1077 
1078 				tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1079 				tcg_gen_xori_tl(n, n, 2);
1080 				tcg_gen_and_tl(cc, z, n);
1081 				tcg_gen_andi_tl(cc, cc, 2);
1082 
1083 				tcg_temp_free(n);
1084 				tcg_temp_free(z);
1085 			}
1086 			break;
1087 		case CC_LE:
1088 			cris_evaluate_flags(dc);
1089 			{
1090 				TCGv n, z;
1091 
1092 				n = tcg_temp_new();
1093 				z = tcg_temp_new();
1094 
1095 				/* To avoid a shift we overlay everything on
1096 				   the V flag.  */
1097 				tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
1098 				tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
1099 
1100 				tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
1101 				tcg_gen_or_tl(cc, z, n);
1102 				tcg_gen_andi_tl(cc, cc, 2);
1103 
1104 				tcg_temp_free(n);
1105 				tcg_temp_free(z);
1106 			}
1107 			break;
1108 		case CC_P:
1109 			cris_evaluate_flags(dc);
1110 			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
1111 			break;
1112 		case CC_A:
1113 			tcg_gen_movi_tl(cc, 1);
1114 			break;
1115 		default:
1116 			BUG();
1117 			break;
1118 	};
1119 }
1120 
cris_store_direct_jmp(DisasContext * dc)1121 static void cris_store_direct_jmp(DisasContext *dc)
1122 {
1123 	/* Store the direct jmp state into the cpu-state.  */
1124 	if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
1125 		if (dc->jmp == JMP_DIRECT) {
1126 			tcg_gen_movi_tl(env_btaken, 1);
1127 		}
1128 		tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1129 		dc->jmp = JMP_INDIRECT;
1130 	}
1131 }
1132 
cris_prepare_cc_branch(DisasContext * dc,int offset,int cond)1133 static void cris_prepare_cc_branch (DisasContext *dc,
1134 				    int offset, int cond)
1135 {
1136 	/* This helps us re-schedule the micro-code to insns in delay-slots
1137 	   before the actual jump.  */
1138 	dc->delayed_branch = 2;
1139 	dc->jmp = JMP_DIRECT_CC;
1140 	dc->jmp_pc = dc->pc + offset;
1141 
1142 	gen_tst_cc (dc, env_btaken, cond);
1143 	tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
1144 }
1145 
1146 
1147 /* jumps, when the dest is in a live reg for example. Direct should be set
1148    when the dest addr is constant to allow tb chaining.  */
cris_prepare_jmp(DisasContext * dc,unsigned int type)1149 static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
1150 {
1151 	/* This helps us re-schedule the micro-code to insns in delay-slots
1152 	   before the actual jump.  */
1153 	dc->delayed_branch = 2;
1154 	dc->jmp = type;
1155 	if (type == JMP_INDIRECT) {
1156 		tcg_gen_movi_tl(env_btaken, 1);
1157 	}
1158 }
1159 
gen_load64(DisasContext * dc,TCGv_i64 dst,TCGv addr)1160 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1161 {
1162 	int mem_index = cpu_mmu_index(dc->env);
1163 
1164 	/* If we get a fault on a delayslot we must keep the jmp state in
1165 	   the cpu-state to be able to re-execute the jmp.  */
1166 	if (dc->delayed_branch == 1)
1167 		cris_store_direct_jmp(dc);
1168 
1169         tcg_gen_qemu_ld64(dst, addr, mem_index);
1170 }
1171 
gen_load(DisasContext * dc,TCGv dst,TCGv addr,unsigned int size,int sign)1172 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
1173 		     unsigned int size, int sign)
1174 {
1175 	int mem_index = cpu_mmu_index(dc->env);
1176 
1177 	/* If we get a fault on a delayslot we must keep the jmp state in
1178 	   the cpu-state to be able to re-execute the jmp.  */
1179 	if (dc->delayed_branch == 1)
1180 		cris_store_direct_jmp(dc);
1181 
1182 	if (size == 1) {
1183 		if (sign)
1184 			tcg_gen_qemu_ld8s(dst, addr, mem_index);
1185 		else
1186 			tcg_gen_qemu_ld8u(dst, addr, mem_index);
1187 	}
1188 	else if (size == 2) {
1189 		if (sign)
1190 			tcg_gen_qemu_ld16s(dst, addr, mem_index);
1191 		else
1192 			tcg_gen_qemu_ld16u(dst, addr, mem_index);
1193 	}
1194 	else if (size == 4) {
1195 		tcg_gen_qemu_ld32u(dst, addr, mem_index);
1196 	}
1197 	else {
1198 		abort();
1199 	}
1200 }
1201 
gen_store(DisasContext * dc,TCGv addr,TCGv val,unsigned int size)1202 static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1203 		       unsigned int size)
1204 {
1205 	int mem_index = cpu_mmu_index(dc->env);
1206 
1207 	/* If we get a fault on a delayslot we must keep the jmp state in
1208 	   the cpu-state to be able to re-execute the jmp.  */
1209 	if (dc->delayed_branch == 1)
1210  		cris_store_direct_jmp(dc);
1211 
1212 
1213 	/* Conditional writes. We only support the kind were X and P are known
1214 	   at translation time.  */
1215 	if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
1216 		dc->postinc = 0;
1217 		cris_evaluate_flags(dc);
1218 		tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1219 		return;
1220 	}
1221 
1222 	if (size == 1)
1223 		tcg_gen_qemu_st8(val, addr, mem_index);
1224 	else if (size == 2)
1225 		tcg_gen_qemu_st16(val, addr, mem_index);
1226 	else
1227 		tcg_gen_qemu_st32(val, addr, mem_index);
1228 
1229 	if (dc->flagx_known && dc->flags_x) {
1230 		cris_evaluate_flags(dc);
1231 		tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1232 	}
1233 }
1234 
t_gen_sext(TCGv d,TCGv s,int size)1235 static inline void t_gen_sext(TCGv d, TCGv s, int size)
1236 {
1237 	if (size == 1)
1238 		tcg_gen_ext8s_i32(d, s);
1239 	else if (size == 2)
1240 		tcg_gen_ext16s_i32(d, s);
1241 	else if(!TCGV_EQUAL(d, s))
1242 		tcg_gen_mov_tl(d, s);
1243 }
1244 
t_gen_zext(TCGv d,TCGv s,int size)1245 static inline void t_gen_zext(TCGv d, TCGv s, int size)
1246 {
1247 	if (size == 1)
1248 		tcg_gen_ext8u_i32(d, s);
1249 	else if (size == 2)
1250 		tcg_gen_ext16u_i32(d, s);
1251 	else if (!TCGV_EQUAL(d, s))
1252 		tcg_gen_mov_tl(d, s);
1253 }
1254 
1255 #if DISAS_CRIS
memsize_char(int size)1256 static char memsize_char(int size)
1257 {
1258 	switch (size)
1259 	{
1260 		case 1: return 'b';  break;
1261 		case 2: return 'w';  break;
1262 		case 4: return 'd';  break;
1263 		default:
1264 			return 'x';
1265 			break;
1266 	}
1267 }
1268 #endif
1269 
memsize_z(DisasContext * dc)1270 static inline unsigned int memsize_z(DisasContext *dc)
1271 {
1272 	return dc->zsize + 1;
1273 }
1274 
memsize_zz(DisasContext * dc)1275 static inline unsigned int memsize_zz(DisasContext *dc)
1276 {
1277 	switch (dc->zzsize)
1278 	{
1279 		case 0: return 1;
1280 		case 1: return 2;
1281 		default:
1282 			return 4;
1283 	}
1284 }
1285 
do_postinc(DisasContext * dc,int size)1286 static inline void do_postinc (DisasContext *dc, int size)
1287 {
1288 	if (dc->postinc)
1289 		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1290 }
1291 
dec_prep_move_r(DisasContext * dc,int rs,int rd,int size,int s_ext,TCGv dst)1292 static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1293 				   int size, int s_ext, TCGv dst)
1294 {
1295 	if (s_ext)
1296 		t_gen_sext(dst, cpu_R[rs], size);
1297 	else
1298 		t_gen_zext(dst, cpu_R[rs], size);
1299 }
1300 
1301 /* Prepare T0 and T1 for a register alu operation.
1302    s_ext decides if the operand1 should be sign-extended or zero-extended when
1303    needed.  */
dec_prep_alu_r(DisasContext * dc,int rs,int rd,int size,int s_ext,TCGv dst,TCGv src)1304 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1305 			  int size, int s_ext, TCGv dst, TCGv src)
1306 {
1307 	dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1308 
1309 	if (s_ext)
1310 		t_gen_sext(dst, cpu_R[rd], size);
1311 	else
1312 		t_gen_zext(dst, cpu_R[rd], size);
1313 }
1314 
dec_prep_move_m(DisasContext * dc,int s_ext,int memsize,TCGv dst)1315 static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1316 			   TCGv dst)
1317 {
1318 	unsigned int rs;
1319 	uint32_t imm;
1320 	int is_imm;
1321 	int insn_len = 2;
1322 
1323 	rs = dc->op1;
1324 	is_imm = rs == 15 && dc->postinc;
1325 
1326 	/* Load [$rs] onto T1.  */
1327 	if (is_imm) {
1328 		insn_len = 2 + memsize;
1329 		if (memsize == 1)
1330 			insn_len++;
1331 
1332 		imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
1333 		tcg_gen_movi_tl(dst, imm);
1334 		dc->postinc = 0;
1335 	} else {
1336 		cris_flush_cc_state(dc);
1337 		gen_load(dc, dst, cpu_R[rs], memsize, 0);
1338 		if (s_ext)
1339 			t_gen_sext(dst, dst, memsize);
1340 		else
1341 			t_gen_zext(dst, dst, memsize);
1342 	}
1343 	return insn_len;
1344 }
1345 
1346 /* Prepare T0 and T1 for a memory + alu operation.
1347    s_ext decides if the operand1 should be sign-extended or zero-extended when
1348    needed.  */
dec_prep_alu_m(DisasContext * dc,int s_ext,int memsize,TCGv dst,TCGv src)1349 static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
1350 			  TCGv dst, TCGv src)
1351 {
1352 	int insn_len;
1353 
1354 	insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
1355 	tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1356 	return insn_len;
1357 }
1358 
1359 #if DISAS_CRIS
cc_name(int cc)1360 static const char *cc_name(int cc)
1361 {
1362 	static const char *cc_names[16] = {
1363 		"cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1364 		"ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1365 	};
1366 	assert(cc < 16);
1367 	return cc_names[cc];
1368 }
1369 #endif
1370 
1371 /* Start of insn decoders.  */
1372 
dec_bccq(DisasContext * dc)1373 static int dec_bccq(DisasContext *dc)
1374 {
1375 	int32_t offset;
1376 	int sign;
1377 	uint32_t cond = dc->op2;
1378 
1379 	offset = EXTRACT_FIELD (dc->ir, 1, 7);
1380 	sign = EXTRACT_FIELD(dc->ir, 0, 0);
1381 
1382 	offset *= 2;
1383 	offset |= sign << 8;
1384 	offset = sign_extend(offset, 8);
1385 
1386 	LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1387 
1388 	/* op2 holds the condition-code.  */
1389 	cris_cc_mask(dc, 0);
1390 	cris_prepare_cc_branch (dc, offset, cond);
1391 	return 2;
1392 }
dec_addoq(DisasContext * dc)1393 static int dec_addoq(DisasContext *dc)
1394 {
1395 	int32_t imm;
1396 
1397 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1398 	imm = sign_extend(dc->op1, 7);
1399 
1400 	LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1401 	cris_cc_mask(dc, 0);
1402 	/* Fetch register operand,  */
1403 	tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1404 
1405 	return 2;
1406 }
dec_addq(DisasContext * dc)1407 static int dec_addq(DisasContext *dc)
1408 {
1409 	LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1410 
1411 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1412 
1413 	cris_cc_mask(dc, CC_MASK_NZVC);
1414 
1415 	cris_alu(dc, CC_OP_ADD,
1416 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1417 	return 2;
1418 }
dec_moveq(DisasContext * dc)1419 static int dec_moveq(DisasContext *dc)
1420 {
1421 	uint32_t imm;
1422 
1423 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1424 	imm = sign_extend(dc->op1, 5);
1425 	LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1426 
1427 	tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1428 	return 2;
1429 }
dec_subq(DisasContext * dc)1430 static int dec_subq(DisasContext *dc)
1431 {
1432 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1433 
1434 	LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1435 
1436 	cris_cc_mask(dc, CC_MASK_NZVC);
1437 	cris_alu(dc, CC_OP_SUB,
1438 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
1439 	return 2;
1440 }
dec_cmpq(DisasContext * dc)1441 static int dec_cmpq(DisasContext *dc)
1442 {
1443 	uint32_t imm;
1444 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1445 	imm = sign_extend(dc->op1, 5);
1446 
1447 	LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1448 	cris_cc_mask(dc, CC_MASK_NZVC);
1449 
1450 	cris_alu(dc, CC_OP_CMP,
1451 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1452 	return 2;
1453 }
dec_andq(DisasContext * dc)1454 static int dec_andq(DisasContext *dc)
1455 {
1456 	uint32_t imm;
1457 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1458 	imm = sign_extend(dc->op1, 5);
1459 
1460 	LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1461 	cris_cc_mask(dc, CC_MASK_NZ);
1462 
1463 	cris_alu(dc, CC_OP_AND,
1464 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1465 	return 2;
1466 }
dec_orq(DisasContext * dc)1467 static int dec_orq(DisasContext *dc)
1468 {
1469 	uint32_t imm;
1470 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1471 	imm = sign_extend(dc->op1, 5);
1472 	LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1473 	cris_cc_mask(dc, CC_MASK_NZ);
1474 
1475 	cris_alu(dc, CC_OP_OR,
1476 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
1477 	return 2;
1478 }
dec_btstq(DisasContext * dc)1479 static int dec_btstq(DisasContext *dc)
1480 {
1481 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1482 	LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1483 
1484 	cris_cc_mask(dc, CC_MASK_NZ);
1485 	cris_evaluate_flags(dc);
1486 	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1487 			tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
1488 	cris_alu(dc, CC_OP_MOVE,
1489 		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1490 	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1491 	dc->flags_uptodate = 1;
1492 	return 2;
1493 }
dec_asrq(DisasContext * dc)1494 static int dec_asrq(DisasContext *dc)
1495 {
1496 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1497 	LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1498 	cris_cc_mask(dc, CC_MASK_NZ);
1499 
1500 	tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1501 	cris_alu(dc, CC_OP_MOVE,
1502 		    cpu_R[dc->op2],
1503 		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1504 	return 2;
1505 }
dec_lslq(DisasContext * dc)1506 static int dec_lslq(DisasContext *dc)
1507 {
1508 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1509 	LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1510 
1511 	cris_cc_mask(dc, CC_MASK_NZ);
1512 
1513 	tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1514 
1515 	cris_alu(dc, CC_OP_MOVE,
1516 		    cpu_R[dc->op2],
1517 		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1518 	return 2;
1519 }
dec_lsrq(DisasContext * dc)1520 static int dec_lsrq(DisasContext *dc)
1521 {
1522 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1523 	LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1524 
1525 	cris_cc_mask(dc, CC_MASK_NZ);
1526 
1527 	tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1528 	cris_alu(dc, CC_OP_MOVE,
1529 		    cpu_R[dc->op2],
1530 		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
1531 	return 2;
1532 }
1533 
dec_move_r(DisasContext * dc)1534 static int dec_move_r(DisasContext *dc)
1535 {
1536 	int size = memsize_zz(dc);
1537 
1538 	LOG_DIS("move.%c $r%u, $r%u\n",
1539 		    memsize_char(size), dc->op1, dc->op2);
1540 
1541 	cris_cc_mask(dc, CC_MASK_NZ);
1542 	if (size == 4) {
1543 		dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1544 		cris_cc_mask(dc, CC_MASK_NZ);
1545 		cris_update_cc_op(dc, CC_OP_MOVE, 4);
1546 		cris_update_cc_x(dc);
1547 		cris_update_result(dc, cpu_R[dc->op2]);
1548 	}
1549 	else {
1550 		TCGv t0;
1551 
1552 		t0 = tcg_temp_new();
1553 		dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1554 		cris_alu(dc, CC_OP_MOVE,
1555 			 cpu_R[dc->op2],
1556 			 cpu_R[dc->op2], t0, size);
1557 		tcg_temp_free(t0);
1558 	}
1559 	return 2;
1560 }
1561 
dec_scc_r(DisasContext * dc)1562 static int dec_scc_r(DisasContext *dc)
1563 {
1564 	int cond = dc->op2;
1565 
1566 	LOG_DIS("s%s $r%u\n",
1567 		    cc_name(cond), dc->op1);
1568 
1569 	if (cond != CC_A)
1570 	{
1571 		int l1;
1572 
1573 		gen_tst_cc (dc, cpu_R[dc->op1], cond);
1574 		l1 = gen_new_label();
1575 		tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
1576 		tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1577 		gen_set_label(l1);
1578 	}
1579 	else
1580 		tcg_gen_movi_tl(cpu_R[dc->op1], 1);
1581 
1582 	cris_cc_mask(dc, 0);
1583 	return 2;
1584 }
1585 
cris_alu_alloc_temps(DisasContext * dc,int size,TCGv * t)1586 static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1587 {
1588 	if (size == 4) {
1589 		t[0] = cpu_R[dc->op2];
1590 		t[1] = cpu_R[dc->op1];
1591 	} else {
1592 		t[0] = tcg_temp_new();
1593 		t[1] = tcg_temp_new();
1594 	}
1595 }
1596 
cris_alu_free_temps(DisasContext * dc,int size,TCGv * t)1597 static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
1598 {
1599 	if (size != 4) {
1600 		tcg_temp_free(t[0]);
1601 		tcg_temp_free(t[1]);
1602 	}
1603 }
1604 
dec_and_r(DisasContext * dc)1605 static int dec_and_r(DisasContext *dc)
1606 {
1607 	TCGv t[2];
1608 	int size = memsize_zz(dc);
1609 
1610 	LOG_DIS("and.%c $r%u, $r%u\n",
1611 		    memsize_char(size), dc->op1, dc->op2);
1612 
1613 	cris_cc_mask(dc, CC_MASK_NZ);
1614 
1615 	cris_alu_alloc_temps(dc, size, t);
1616 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1617 	cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1618 	cris_alu_free_temps(dc, size, t);
1619 	return 2;
1620 }
1621 
dec_lz_r(DisasContext * dc)1622 static int dec_lz_r(DisasContext *dc)
1623 {
1624 	TCGv t0;
1625 	LOG_DIS("lz $r%u, $r%u\n",
1626 		    dc->op1, dc->op2);
1627 	cris_cc_mask(dc, CC_MASK_NZ);
1628 	t0 = tcg_temp_new();
1629 	dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1630 	cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1631 	tcg_temp_free(t0);
1632 	return 2;
1633 }
1634 
dec_lsl_r(DisasContext * dc)1635 static int dec_lsl_r(DisasContext *dc)
1636 {
1637 	TCGv t[2];
1638 	int size = memsize_zz(dc);
1639 
1640 	LOG_DIS("lsl.%c $r%u, $r%u\n",
1641 		    memsize_char(size), dc->op1, dc->op2);
1642 
1643 	cris_cc_mask(dc, CC_MASK_NZ);
1644 	cris_alu_alloc_temps(dc, size, t);
1645 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1646 	tcg_gen_andi_tl(t[1], t[1], 63);
1647 	cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1648 	cris_alu_alloc_temps(dc, size, t);
1649 	return 2;
1650 }
1651 
dec_lsr_r(DisasContext * dc)1652 static int dec_lsr_r(DisasContext *dc)
1653 {
1654 	TCGv t[2];
1655 	int size = memsize_zz(dc);
1656 
1657 	LOG_DIS("lsr.%c $r%u, $r%u\n",
1658 		    memsize_char(size), dc->op1, dc->op2);
1659 
1660 	cris_cc_mask(dc, CC_MASK_NZ);
1661 	cris_alu_alloc_temps(dc, size, t);
1662 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1663 	tcg_gen_andi_tl(t[1], t[1], 63);
1664 	cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1665 	cris_alu_free_temps(dc, size, t);
1666 	return 2;
1667 }
1668 
dec_asr_r(DisasContext * dc)1669 static int dec_asr_r(DisasContext *dc)
1670 {
1671 	TCGv t[2];
1672 	int size = memsize_zz(dc);
1673 
1674 	LOG_DIS("asr.%c $r%u, $r%u\n",
1675 		    memsize_char(size), dc->op1, dc->op2);
1676 
1677 	cris_cc_mask(dc, CC_MASK_NZ);
1678 	cris_alu_alloc_temps(dc, size, t);
1679 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1680 	tcg_gen_andi_tl(t[1], t[1], 63);
1681 	cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1682 	cris_alu_free_temps(dc, size, t);
1683 	return 2;
1684 }
1685 
dec_muls_r(DisasContext * dc)1686 static int dec_muls_r(DisasContext *dc)
1687 {
1688 	TCGv t[2];
1689 	int size = memsize_zz(dc);
1690 
1691 	LOG_DIS("muls.%c $r%u, $r%u\n",
1692 		    memsize_char(size), dc->op1, dc->op2);
1693 	cris_cc_mask(dc, CC_MASK_NZV);
1694 	cris_alu_alloc_temps(dc, size, t);
1695 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1696 
1697 	cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1698 	cris_alu_free_temps(dc, size, t);
1699 	return 2;
1700 }
1701 
dec_mulu_r(DisasContext * dc)1702 static int dec_mulu_r(DisasContext *dc)
1703 {
1704 	TCGv t[2];
1705 	int size = memsize_zz(dc);
1706 
1707 	LOG_DIS("mulu.%c $r%u, $r%u\n",
1708 		    memsize_char(size), dc->op1, dc->op2);
1709 	cris_cc_mask(dc, CC_MASK_NZV);
1710 	cris_alu_alloc_temps(dc, size, t);
1711 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1712 
1713 	cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1714 	cris_alu_alloc_temps(dc, size, t);
1715 	return 2;
1716 }
1717 
1718 
dec_dstep_r(DisasContext * dc)1719 static int dec_dstep_r(DisasContext *dc)
1720 {
1721 	LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1722 	cris_cc_mask(dc, CC_MASK_NZ);
1723 	cris_alu(dc, CC_OP_DSTEP,
1724 		    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1725 	return 2;
1726 }
1727 
dec_xor_r(DisasContext * dc)1728 static int dec_xor_r(DisasContext *dc)
1729 {
1730 	TCGv t[2];
1731 	int size = memsize_zz(dc);
1732 	LOG_DIS("xor.%c $r%u, $r%u\n",
1733 		    memsize_char(size), dc->op1, dc->op2);
1734 	BUG_ON(size != 4); /* xor is dword.  */
1735 	cris_cc_mask(dc, CC_MASK_NZ);
1736 	cris_alu_alloc_temps(dc, size, t);
1737 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1738 
1739 	cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1740 	cris_alu_free_temps(dc, size, t);
1741 	return 2;
1742 }
1743 
dec_bound_r(DisasContext * dc)1744 static int dec_bound_r(DisasContext *dc)
1745 {
1746 	TCGv l0;
1747 	int size = memsize_zz(dc);
1748 	LOG_DIS("bound.%c $r%u, $r%u\n",
1749 		    memsize_char(size), dc->op1, dc->op2);
1750 	cris_cc_mask(dc, CC_MASK_NZ);
1751 	l0 = tcg_temp_local_new();
1752 	dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1753 	cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1754 	tcg_temp_free(l0);
1755 	return 2;
1756 }
1757 
dec_cmp_r(DisasContext * dc)1758 static int dec_cmp_r(DisasContext *dc)
1759 {
1760 	TCGv t[2];
1761 	int size = memsize_zz(dc);
1762 	LOG_DIS("cmp.%c $r%u, $r%u\n",
1763 		    memsize_char(size), dc->op1, dc->op2);
1764 	cris_cc_mask(dc, CC_MASK_NZVC);
1765 	cris_alu_alloc_temps(dc, size, t);
1766 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1767 
1768 	cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1769 	cris_alu_free_temps(dc, size, t);
1770 	return 2;
1771 }
1772 
dec_abs_r(DisasContext * dc)1773 static int dec_abs_r(DisasContext *dc)
1774 {
1775 	TCGv t0;
1776 
1777 	LOG_DIS("abs $r%u, $r%u\n",
1778 		    dc->op1, dc->op2);
1779 	cris_cc_mask(dc, CC_MASK_NZ);
1780 
1781 	t0 = tcg_temp_new();
1782 	tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
1783 	tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
1784 	tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
1785 	tcg_temp_free(t0);
1786 
1787 	cris_alu(dc, CC_OP_MOVE,
1788 		    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1789 	return 2;
1790 }
1791 
dec_add_r(DisasContext * dc)1792 static int dec_add_r(DisasContext *dc)
1793 {
1794 	TCGv t[2];
1795 	int size = memsize_zz(dc);
1796 	LOG_DIS("add.%c $r%u, $r%u\n",
1797 		    memsize_char(size), dc->op1, dc->op2);
1798 	cris_cc_mask(dc, CC_MASK_NZVC);
1799 	cris_alu_alloc_temps(dc, size, t);
1800 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1801 
1802 	cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1803 	cris_alu_free_temps(dc, size, t);
1804 	return 2;
1805 }
1806 
dec_addc_r(DisasContext * dc)1807 static int dec_addc_r(DisasContext *dc)
1808 {
1809 	LOG_DIS("addc $r%u, $r%u\n",
1810 		    dc->op1, dc->op2);
1811 	cris_evaluate_flags(dc);
1812 	/* Set for this insn.  */
1813 	dc->flagx_known = 1;
1814 	dc->flags_x = X_FLAG;
1815 
1816 	cris_cc_mask(dc, CC_MASK_NZVC);
1817 	cris_alu(dc, CC_OP_ADDC,
1818 		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1819 	return 2;
1820 }
1821 
dec_mcp_r(DisasContext * dc)1822 static int dec_mcp_r(DisasContext *dc)
1823 {
1824 	LOG_DIS("mcp $p%u, $r%u\n",
1825 		     dc->op2, dc->op1);
1826 	cris_evaluate_flags(dc);
1827 	cris_cc_mask(dc, CC_MASK_RNZV);
1828 	cris_alu(dc, CC_OP_MCP,
1829 		    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1830 	return 2;
1831 }
1832 
1833 #if DISAS_CRIS
swapmode_name(int mode,char * modename)1834 static char * swapmode_name(int mode, char *modename) {
1835 	int i = 0;
1836 	if (mode & 8)
1837 		modename[i++] = 'n';
1838 	if (mode & 4)
1839 		modename[i++] = 'w';
1840 	if (mode & 2)
1841 		modename[i++] = 'b';
1842 	if (mode & 1)
1843 		modename[i++] = 'r';
1844 	modename[i++] = 0;
1845 	return modename;
1846 }
1847 #endif
1848 
dec_swap_r(DisasContext * dc)1849 static int dec_swap_r(DisasContext *dc)
1850 {
1851 	TCGv t0;
1852 #if DISAS_CRIS
1853 	char modename[4];
1854 #endif
1855 	LOG_DIS("swap%s $r%u\n",
1856 		     swapmode_name(dc->op2, modename), dc->op1);
1857 
1858 	cris_cc_mask(dc, CC_MASK_NZ);
1859 	t0 = tcg_temp_new();
1860 	t_gen_mov_TN_reg(t0, dc->op1);
1861 	if (dc->op2 & 8)
1862 		tcg_gen_not_tl(t0, t0);
1863 	if (dc->op2 & 4)
1864 		t_gen_swapw(t0, t0);
1865 	if (dc->op2 & 2)
1866 		t_gen_swapb(t0, t0);
1867 	if (dc->op2 & 1)
1868 		t_gen_swapr(t0, t0);
1869 	cris_alu(dc, CC_OP_MOVE,
1870 		    cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1871 	tcg_temp_free(t0);
1872 	return 2;
1873 }
1874 
dec_or_r(DisasContext * dc)1875 static int dec_or_r(DisasContext *dc)
1876 {
1877 	TCGv t[2];
1878 	int size = memsize_zz(dc);
1879 	LOG_DIS("or.%c $r%u, $r%u\n",
1880 		    memsize_char(size), dc->op1, dc->op2);
1881 	cris_cc_mask(dc, CC_MASK_NZ);
1882 	cris_alu_alloc_temps(dc, size, t);
1883 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1884 	cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1885 	cris_alu_free_temps(dc, size, t);
1886 	return 2;
1887 }
1888 
dec_addi_r(DisasContext * dc)1889 static int dec_addi_r(DisasContext *dc)
1890 {
1891 	TCGv t0;
1892 	LOG_DIS("addi.%c $r%u, $r%u\n",
1893 		    memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1894 	cris_cc_mask(dc, 0);
1895 	t0 = tcg_temp_new();
1896 	tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1897 	tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1898 	tcg_temp_free(t0);
1899 	return 2;
1900 }
1901 
dec_addi_acr(DisasContext * dc)1902 static int dec_addi_acr(DisasContext *dc)
1903 {
1904 	TCGv t0;
1905 	LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1906 		  memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1907 	cris_cc_mask(dc, 0);
1908 	t0 = tcg_temp_new();
1909 	tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
1910 	tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1911 	tcg_temp_free(t0);
1912 	return 2;
1913 }
1914 
dec_neg_r(DisasContext * dc)1915 static int dec_neg_r(DisasContext *dc)
1916 {
1917 	TCGv t[2];
1918 	int size = memsize_zz(dc);
1919 	LOG_DIS("neg.%c $r%u, $r%u\n",
1920 		    memsize_char(size), dc->op1, dc->op2);
1921 	cris_cc_mask(dc, CC_MASK_NZVC);
1922 	cris_alu_alloc_temps(dc, size, t);
1923 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1924 
1925 	cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1926 	cris_alu_free_temps(dc, size, t);
1927 	return 2;
1928 }
1929 
dec_btst_r(DisasContext * dc)1930 static int dec_btst_r(DisasContext *dc)
1931 {
1932 	LOG_DIS("btst $r%u, $r%u\n",
1933 		    dc->op1, dc->op2);
1934 	cris_cc_mask(dc, CC_MASK_NZ);
1935 	cris_evaluate_flags(dc);
1936 	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
1937 			cpu_R[dc->op1], cpu_PR[PR_CCS]);
1938 	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1939 		 cpu_R[dc->op2], cpu_R[dc->op2], 4);
1940 	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1941 	dc->flags_uptodate = 1;
1942 	return 2;
1943 }
1944 
dec_sub_r(DisasContext * dc)1945 static int dec_sub_r(DisasContext *dc)
1946 {
1947 	TCGv t[2];
1948 	int size = memsize_zz(dc);
1949 	LOG_DIS("sub.%c $r%u, $r%u\n",
1950 		    memsize_char(size), dc->op1, dc->op2);
1951 	cris_cc_mask(dc, CC_MASK_NZVC);
1952 	cris_alu_alloc_temps(dc, size, t);
1953 	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1954 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1955 	cris_alu_free_temps(dc, size, t);
1956 	return 2;
1957 }
1958 
1959 /* Zero extension. From size to dword.  */
dec_movu_r(DisasContext * dc)1960 static int dec_movu_r(DisasContext *dc)
1961 {
1962 	TCGv t0;
1963 	int size = memsize_z(dc);
1964 	LOG_DIS("movu.%c $r%u, $r%u\n",
1965 		    memsize_char(size),
1966 		    dc->op1, dc->op2);
1967 
1968 	cris_cc_mask(dc, CC_MASK_NZ);
1969 	t0 = tcg_temp_new();
1970 	dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1971 	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1972 	tcg_temp_free(t0);
1973 	return 2;
1974 }
1975 
1976 /* Sign extension. From size to dword.  */
dec_movs_r(DisasContext * dc)1977 static int dec_movs_r(DisasContext *dc)
1978 {
1979 	TCGv t0;
1980 	int size = memsize_z(dc);
1981 	LOG_DIS("movs.%c $r%u, $r%u\n",
1982 		    memsize_char(size),
1983 		    dc->op1, dc->op2);
1984 
1985 	cris_cc_mask(dc, CC_MASK_NZ);
1986 	t0 = tcg_temp_new();
1987 	/* Size can only be qi or hi.  */
1988 	t_gen_sext(t0, cpu_R[dc->op1], size);
1989 	cris_alu(dc, CC_OP_MOVE,
1990 		    cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1991 	tcg_temp_free(t0);
1992 	return 2;
1993 }
1994 
1995 /* zero extension. From size to dword.  */
dec_addu_r(DisasContext * dc)1996 static int dec_addu_r(DisasContext *dc)
1997 {
1998 	TCGv t0;
1999 	int size = memsize_z(dc);
2000 	LOG_DIS("addu.%c $r%u, $r%u\n",
2001 		    memsize_char(size),
2002 		    dc->op1, dc->op2);
2003 
2004 	cris_cc_mask(dc, CC_MASK_NZVC);
2005 	t0 = tcg_temp_new();
2006 	/* Size can only be qi or hi.  */
2007 	t_gen_zext(t0, cpu_R[dc->op1], size);
2008 	cris_alu(dc, CC_OP_ADD,
2009 		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2010 	tcg_temp_free(t0);
2011 	return 2;
2012 }
2013 
2014 /* Sign extension. From size to dword.  */
dec_adds_r(DisasContext * dc)2015 static int dec_adds_r(DisasContext *dc)
2016 {
2017 	TCGv t0;
2018 	int size = memsize_z(dc);
2019 	LOG_DIS("adds.%c $r%u, $r%u\n",
2020 		    memsize_char(size),
2021 		    dc->op1, dc->op2);
2022 
2023 	cris_cc_mask(dc, CC_MASK_NZVC);
2024 	t0 = tcg_temp_new();
2025 	/* Size can only be qi or hi.  */
2026 	t_gen_sext(t0, cpu_R[dc->op1], size);
2027 	cris_alu(dc, CC_OP_ADD,
2028 		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2029 	tcg_temp_free(t0);
2030 	return 2;
2031 }
2032 
2033 /* Zero extension. From size to dword.  */
dec_subu_r(DisasContext * dc)2034 static int dec_subu_r(DisasContext *dc)
2035 {
2036 	TCGv t0;
2037 	int size = memsize_z(dc);
2038 	LOG_DIS("subu.%c $r%u, $r%u\n",
2039 		    memsize_char(size),
2040 		    dc->op1, dc->op2);
2041 
2042 	cris_cc_mask(dc, CC_MASK_NZVC);
2043 	t0 = tcg_temp_new();
2044 	/* Size can only be qi or hi.  */
2045 	t_gen_zext(t0, cpu_R[dc->op1], size);
2046 	cris_alu(dc, CC_OP_SUB,
2047 		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2048 	tcg_temp_free(t0);
2049 	return 2;
2050 }
2051 
2052 /* Sign extension. From size to dword.  */
dec_subs_r(DisasContext * dc)2053 static int dec_subs_r(DisasContext *dc)
2054 {
2055 	TCGv t0;
2056 	int size = memsize_z(dc);
2057 	LOG_DIS("subs.%c $r%u, $r%u\n",
2058 		    memsize_char(size),
2059 		    dc->op1, dc->op2);
2060 
2061 	cris_cc_mask(dc, CC_MASK_NZVC);
2062 	t0 = tcg_temp_new();
2063 	/* Size can only be qi or hi.  */
2064 	t_gen_sext(t0, cpu_R[dc->op1], size);
2065 	cris_alu(dc, CC_OP_SUB,
2066 		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
2067 	tcg_temp_free(t0);
2068 	return 2;
2069 }
2070 
dec_setclrf(DisasContext * dc)2071 static int dec_setclrf(DisasContext *dc)
2072 {
2073 	uint32_t flags;
2074 	int set = (~dc->opcode >> 2) & 1;
2075 
2076 
2077 	flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
2078 		| EXTRACT_FIELD(dc->ir, 0, 3);
2079 	if (set && flags == 0) {
2080 		LOG_DIS("nop\n");
2081 		return 2;
2082 	} else if (!set && (flags & 0x20)) {
2083 		LOG_DIS("di\n");
2084 	}
2085 	else {
2086 		LOG_DIS("%sf %x\n",
2087 			     set ? "set" : "clr",
2088 			    flags);
2089 	}
2090 
2091 	/* User space is not allowed to touch these. Silently ignore.  */
2092 	if (dc->tb_flags & U_FLAG) {
2093 		flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2094 	}
2095 
2096 	if (flags & X_FLAG) {
2097 		dc->flagx_known = 1;
2098 		if (set)
2099 			dc->flags_x = X_FLAG;
2100 		else
2101 			dc->flags_x = 0;
2102 	}
2103 
2104 	/* Break the TB if any of the SPI flag changes.  */
2105 	if (flags & (P_FLAG | S_FLAG)) {
2106 		tcg_gen_movi_tl(env_pc, dc->pc + 2);
2107 		dc->is_jmp = DISAS_UPDATE;
2108 		dc->cpustate_changed = 1;
2109 	}
2110 
2111 	/* For the I flag, only act on posedge.  */
2112 	if ((flags & I_FLAG)) {
2113 		tcg_gen_movi_tl(env_pc, dc->pc + 2);
2114 		dc->is_jmp = DISAS_UPDATE;
2115 		dc->cpustate_changed = 1;
2116 	}
2117 
2118 
2119 	/* Simply decode the flags.  */
2120 	cris_evaluate_flags (dc);
2121 	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2122 	cris_update_cc_x(dc);
2123 	tcg_gen_movi_tl(cc_op, dc->cc_op);
2124 
2125 	if (set) {
2126 		if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
2127 			/* Enter user mode.  */
2128 			t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
2129 			tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
2130 			dc->cpustate_changed = 1;
2131 		}
2132 		tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
2133 	}
2134 	else
2135 		tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
2136 
2137 	dc->flags_uptodate = 1;
2138 	dc->clear_x = 0;
2139 	return 2;
2140 }
2141 
dec_move_rs(DisasContext * dc)2142 static int dec_move_rs(DisasContext *dc)
2143 {
2144 	LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
2145 	cris_cc_mask(dc, 0);
2146 	gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
2147 	return 2;
2148 }
dec_move_sr(DisasContext * dc)2149 static int dec_move_sr(DisasContext *dc)
2150 {
2151 	LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
2152 	cris_cc_mask(dc, 0);
2153 	gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
2154 	return 2;
2155 }
2156 
dec_move_rp(DisasContext * dc)2157 static int dec_move_rp(DisasContext *dc)
2158 {
2159 	TCGv t[2];
2160 	LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
2161 	cris_cc_mask(dc, 0);
2162 
2163 	t[0] = tcg_temp_new();
2164 	if (dc->op2 == PR_CCS) {
2165 		cris_evaluate_flags(dc);
2166 		t_gen_mov_TN_reg(t[0], dc->op1);
2167 		if (dc->tb_flags & U_FLAG) {
2168 			t[1] = tcg_temp_new();
2169 			/* User space is not allowed to touch all flags.  */
2170 			tcg_gen_andi_tl(t[0], t[0], 0x39f);
2171 			tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
2172 			tcg_gen_or_tl(t[0], t[1], t[0]);
2173 			tcg_temp_free(t[1]);
2174 		}
2175 	}
2176 	else
2177 		t_gen_mov_TN_reg(t[0], dc->op1);
2178 
2179 	t_gen_mov_preg_TN(dc, dc->op2, t[0]);
2180 	if (dc->op2 == PR_CCS) {
2181 		cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2182 		dc->flags_uptodate = 1;
2183 	}
2184 	tcg_temp_free(t[0]);
2185 	return 2;
2186 }
dec_move_pr(DisasContext * dc)2187 static int dec_move_pr(DisasContext *dc)
2188 {
2189 	TCGv t0;
2190 	LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
2191 	cris_cc_mask(dc, 0);
2192 
2193 	if (dc->op2 == PR_CCS)
2194 		cris_evaluate_flags(dc);
2195 
2196         if (dc->op2 == PR_DZ) {
2197 		tcg_gen_movi_tl(cpu_R[dc->op1], 0);
2198         } else {
2199 		t0 = tcg_temp_new();
2200 		t_gen_mov_TN_preg(t0, dc->op2);
2201 		cris_alu(dc, CC_OP_MOVE,
2202 			 cpu_R[dc->op1], cpu_R[dc->op1], t0,
2203 			 preg_sizes[dc->op2]);
2204 		tcg_temp_free(t0);
2205 	}
2206 	return 2;
2207 }
2208 
dec_move_mr(DisasContext * dc)2209 static int dec_move_mr(DisasContext *dc)
2210 {
2211 	int memsize = memsize_zz(dc);
2212 	int insn_len;
2213 	LOG_DIS("move.%c [$r%u%s, $r%u\n",
2214 		    memsize_char(memsize),
2215 		    dc->op1, dc->postinc ? "+]" : "]",
2216 		    dc->op2);
2217 
2218 	if (memsize == 4) {
2219 		insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
2220 		cris_cc_mask(dc, CC_MASK_NZ);
2221 		cris_update_cc_op(dc, CC_OP_MOVE, 4);
2222 		cris_update_cc_x(dc);
2223 		cris_update_result(dc, cpu_R[dc->op2]);
2224 	}
2225 	else {
2226 		TCGv t0;
2227 
2228 		t0 = tcg_temp_new();
2229 		insn_len = dec_prep_move_m(dc, 0, memsize, t0);
2230 		cris_cc_mask(dc, CC_MASK_NZ);
2231 		cris_alu(dc, CC_OP_MOVE,
2232 			    cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2233 		tcg_temp_free(t0);
2234 	}
2235 	do_postinc(dc, memsize);
2236 	return insn_len;
2237 }
2238 
cris_alu_m_alloc_temps(TCGv * t)2239 static inline void cris_alu_m_alloc_temps(TCGv *t)
2240 {
2241 	t[0] = tcg_temp_new();
2242 	t[1] = tcg_temp_new();
2243 }
2244 
cris_alu_m_free_temps(TCGv * t)2245 static inline void cris_alu_m_free_temps(TCGv *t)
2246 {
2247 	tcg_temp_free(t[0]);
2248 	tcg_temp_free(t[1]);
2249 }
2250 
dec_movs_m(DisasContext * dc)2251 static int dec_movs_m(DisasContext *dc)
2252 {
2253 	TCGv t[2];
2254 	int memsize = memsize_z(dc);
2255 	int insn_len;
2256 	LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2257 		    memsize_char(memsize),
2258 		    dc->op1, dc->postinc ? "+]" : "]",
2259 		    dc->op2);
2260 
2261 	cris_alu_m_alloc_temps(t);
2262 	/* sign extend.  */
2263 	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2264 	cris_cc_mask(dc, CC_MASK_NZ);
2265 	cris_alu(dc, CC_OP_MOVE,
2266 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2267 	do_postinc(dc, memsize);
2268 	cris_alu_m_free_temps(t);
2269 	return insn_len;
2270 }
2271 
dec_addu_m(DisasContext * dc)2272 static int dec_addu_m(DisasContext *dc)
2273 {
2274 	TCGv t[2];
2275 	int memsize = memsize_z(dc);
2276 	int insn_len;
2277 	LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2278 		    memsize_char(memsize),
2279 		    dc->op1, dc->postinc ? "+]" : "]",
2280 		    dc->op2);
2281 
2282 	cris_alu_m_alloc_temps(t);
2283 	/* sign extend.  */
2284 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2285 	cris_cc_mask(dc, CC_MASK_NZVC);
2286 	cris_alu(dc, CC_OP_ADD,
2287 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2288 	do_postinc(dc, memsize);
2289 	cris_alu_m_free_temps(t);
2290 	return insn_len;
2291 }
2292 
dec_adds_m(DisasContext * dc)2293 static int dec_adds_m(DisasContext *dc)
2294 {
2295 	TCGv t[2];
2296 	int memsize = memsize_z(dc);
2297 	int insn_len;
2298 	LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2299 		    memsize_char(memsize),
2300 		    dc->op1, dc->postinc ? "+]" : "]",
2301 		    dc->op2);
2302 
2303 	cris_alu_m_alloc_temps(t);
2304 	/* sign extend.  */
2305 	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2306 	cris_cc_mask(dc, CC_MASK_NZVC);
2307 	cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2308 	do_postinc(dc, memsize);
2309 	cris_alu_m_free_temps(t);
2310 	return insn_len;
2311 }
2312 
dec_subu_m(DisasContext * dc)2313 static int dec_subu_m(DisasContext *dc)
2314 {
2315 	TCGv t[2];
2316 	int memsize = memsize_z(dc);
2317 	int insn_len;
2318 	LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2319 		    memsize_char(memsize),
2320 		    dc->op1, dc->postinc ? "+]" : "]",
2321 		    dc->op2);
2322 
2323 	cris_alu_m_alloc_temps(t);
2324 	/* sign extend.  */
2325 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2326 	cris_cc_mask(dc, CC_MASK_NZVC);
2327 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2328 	do_postinc(dc, memsize);
2329 	cris_alu_m_free_temps(t);
2330 	return insn_len;
2331 }
2332 
dec_subs_m(DisasContext * dc)2333 static int dec_subs_m(DisasContext *dc)
2334 {
2335 	TCGv t[2];
2336 	int memsize = memsize_z(dc);
2337 	int insn_len;
2338 	LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2339 		    memsize_char(memsize),
2340 		    dc->op1, dc->postinc ? "+]" : "]",
2341 		    dc->op2);
2342 
2343 	cris_alu_m_alloc_temps(t);
2344 	/* sign extend.  */
2345 	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2346 	cris_cc_mask(dc, CC_MASK_NZVC);
2347 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2348 	do_postinc(dc, memsize);
2349 	cris_alu_m_free_temps(t);
2350 	return insn_len;
2351 }
2352 
dec_movu_m(DisasContext * dc)2353 static int dec_movu_m(DisasContext *dc)
2354 {
2355 	TCGv t[2];
2356 	int memsize = memsize_z(dc);
2357 	int insn_len;
2358 
2359 	LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2360 		    memsize_char(memsize),
2361 		    dc->op1, dc->postinc ? "+]" : "]",
2362 		    dc->op2);
2363 
2364 	cris_alu_m_alloc_temps(t);
2365 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2366 	cris_cc_mask(dc, CC_MASK_NZ);
2367 	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2368 	do_postinc(dc, memsize);
2369 	cris_alu_m_free_temps(t);
2370 	return insn_len;
2371 }
2372 
dec_cmpu_m(DisasContext * dc)2373 static int dec_cmpu_m(DisasContext *dc)
2374 {
2375 	TCGv t[2];
2376 	int memsize = memsize_z(dc);
2377 	int insn_len;
2378 	LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2379 		    memsize_char(memsize),
2380 		    dc->op1, dc->postinc ? "+]" : "]",
2381 		    dc->op2);
2382 
2383 	cris_alu_m_alloc_temps(t);
2384 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2385 	cris_cc_mask(dc, CC_MASK_NZVC);
2386 	cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2387 	do_postinc(dc, memsize);
2388 	cris_alu_m_free_temps(t);
2389 	return insn_len;
2390 }
2391 
dec_cmps_m(DisasContext * dc)2392 static int dec_cmps_m(DisasContext *dc)
2393 {
2394 	TCGv t[2];
2395 	int memsize = memsize_z(dc);
2396 	int insn_len;
2397 	LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2398 		    memsize_char(memsize),
2399 		    dc->op1, dc->postinc ? "+]" : "]",
2400 		    dc->op2);
2401 
2402 	cris_alu_m_alloc_temps(t);
2403 	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2404 	cris_cc_mask(dc, CC_MASK_NZVC);
2405 	cris_alu(dc, CC_OP_CMP,
2406 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2407 		    memsize_zz(dc));
2408 	do_postinc(dc, memsize);
2409 	cris_alu_m_free_temps(t);
2410 	return insn_len;
2411 }
2412 
dec_cmp_m(DisasContext * dc)2413 static int dec_cmp_m(DisasContext *dc)
2414 {
2415 	TCGv t[2];
2416 	int memsize = memsize_zz(dc);
2417 	int insn_len;
2418 	LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2419 		    memsize_char(memsize),
2420 		    dc->op1, dc->postinc ? "+]" : "]",
2421 		    dc->op2);
2422 
2423 	cris_alu_m_alloc_temps(t);
2424 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2425 	cris_cc_mask(dc, CC_MASK_NZVC);
2426 	cris_alu(dc, CC_OP_CMP,
2427 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2428 		    memsize_zz(dc));
2429 	do_postinc(dc, memsize);
2430 	cris_alu_m_free_temps(t);
2431 	return insn_len;
2432 }
2433 
dec_test_m(DisasContext * dc)2434 static int dec_test_m(DisasContext *dc)
2435 {
2436 	TCGv t[2];
2437 	int memsize = memsize_zz(dc);
2438 	int insn_len;
2439 	LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2440 		    memsize_char(memsize),
2441 		    dc->op1, dc->postinc ? "+]" : "]",
2442 		    dc->op2);
2443 
2444 	cris_evaluate_flags(dc);
2445 
2446 	cris_alu_m_alloc_temps(t);
2447 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2448 	cris_cc_mask(dc, CC_MASK_NZ);
2449 	tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2450 
2451 	cris_alu(dc, CC_OP_CMP,
2452 		 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
2453 	do_postinc(dc, memsize);
2454 	cris_alu_m_free_temps(t);
2455 	return insn_len;
2456 }
2457 
dec_and_m(DisasContext * dc)2458 static int dec_and_m(DisasContext *dc)
2459 {
2460 	TCGv t[2];
2461 	int memsize = memsize_zz(dc);
2462 	int insn_len;
2463 	LOG_DIS("and.%c [$r%u%s, $r%u\n",
2464 		    memsize_char(memsize),
2465 		    dc->op1, dc->postinc ? "+]" : "]",
2466 		    dc->op2);
2467 
2468 	cris_alu_m_alloc_temps(t);
2469 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2470 	cris_cc_mask(dc, CC_MASK_NZ);
2471 	cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2472 	do_postinc(dc, memsize);
2473 	cris_alu_m_free_temps(t);
2474 	return insn_len;
2475 }
2476 
dec_add_m(DisasContext * dc)2477 static int dec_add_m(DisasContext *dc)
2478 {
2479 	TCGv t[2];
2480 	int memsize = memsize_zz(dc);
2481 	int insn_len;
2482 	LOG_DIS("add.%c [$r%u%s, $r%u\n",
2483 		    memsize_char(memsize),
2484 		    dc->op1, dc->postinc ? "+]" : "]",
2485 		    dc->op2);
2486 
2487 	cris_alu_m_alloc_temps(t);
2488 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2489 	cris_cc_mask(dc, CC_MASK_NZVC);
2490 	cris_alu(dc, CC_OP_ADD,
2491 		 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2492 	do_postinc(dc, memsize);
2493 	cris_alu_m_free_temps(t);
2494 	return insn_len;
2495 }
2496 
dec_addo_m(DisasContext * dc)2497 static int dec_addo_m(DisasContext *dc)
2498 {
2499 	TCGv t[2];
2500 	int memsize = memsize_zz(dc);
2501 	int insn_len;
2502 	LOG_DIS("add.%c [$r%u%s, $r%u\n",
2503 		    memsize_char(memsize),
2504 		    dc->op1, dc->postinc ? "+]" : "]",
2505 		    dc->op2);
2506 
2507 	cris_alu_m_alloc_temps(t);
2508 	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
2509 	cris_cc_mask(dc, 0);
2510 	cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2511 	do_postinc(dc, memsize);
2512 	cris_alu_m_free_temps(t);
2513 	return insn_len;
2514 }
2515 
dec_bound_m(DisasContext * dc)2516 static int dec_bound_m(DisasContext *dc)
2517 {
2518 	TCGv l[2];
2519 	int memsize = memsize_zz(dc);
2520 	int insn_len;
2521 	LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2522 		    memsize_char(memsize),
2523 		    dc->op1, dc->postinc ? "+]" : "]",
2524 		    dc->op2);
2525 
2526 	l[0] = tcg_temp_local_new();
2527 	l[1] = tcg_temp_local_new();
2528 	insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
2529 	cris_cc_mask(dc, CC_MASK_NZ);
2530 	cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2531 	do_postinc(dc, memsize);
2532 	tcg_temp_free(l[0]);
2533 	tcg_temp_free(l[1]);
2534 	return insn_len;
2535 }
2536 
dec_addc_mr(DisasContext * dc)2537 static int dec_addc_mr(DisasContext *dc)
2538 {
2539 	TCGv t[2];
2540 	int insn_len = 2;
2541 	LOG_DIS("addc [$r%u%s, $r%u\n",
2542 		    dc->op1, dc->postinc ? "+]" : "]",
2543 		    dc->op2);
2544 
2545 	cris_evaluate_flags(dc);
2546 
2547 	/* Set for this insn.  */
2548 	dc->flagx_known = 1;
2549 	dc->flags_x = X_FLAG;
2550 
2551 	cris_alu_m_alloc_temps(t);
2552 	insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2553 	cris_cc_mask(dc, CC_MASK_NZVC);
2554 	cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2555 	do_postinc(dc, 4);
2556 	cris_alu_m_free_temps(t);
2557 	return insn_len;
2558 }
2559 
dec_sub_m(DisasContext * dc)2560 static int dec_sub_m(DisasContext *dc)
2561 {
2562 	TCGv t[2];
2563 	int memsize = memsize_zz(dc);
2564 	int insn_len;
2565 	LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2566 		    memsize_char(memsize),
2567 		    dc->op1, dc->postinc ? "+]" : "]",
2568 		    dc->op2, dc->ir, dc->zzsize);
2569 
2570 	cris_alu_m_alloc_temps(t);
2571 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2572 	cris_cc_mask(dc, CC_MASK_NZVC);
2573 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2574 	do_postinc(dc, memsize);
2575 	cris_alu_m_free_temps(t);
2576 	return insn_len;
2577 }
2578 
dec_or_m(DisasContext * dc)2579 static int dec_or_m(DisasContext *dc)
2580 {
2581 	TCGv t[2];
2582 	int memsize = memsize_zz(dc);
2583 	int insn_len;
2584 	LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2585 		    memsize_char(memsize),
2586 		    dc->op1, dc->postinc ? "+]" : "]",
2587 		    dc->op2, dc->pc);
2588 
2589 	cris_alu_m_alloc_temps(t);
2590 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2591 	cris_cc_mask(dc, CC_MASK_NZ);
2592 	cris_alu(dc, CC_OP_OR,
2593 		    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2594 	do_postinc(dc, memsize);
2595 	cris_alu_m_free_temps(t);
2596 	return insn_len;
2597 }
2598 
dec_move_mp(DisasContext * dc)2599 static int dec_move_mp(DisasContext *dc)
2600 {
2601 	TCGv t[2];
2602 	int memsize = memsize_zz(dc);
2603 	int insn_len = 2;
2604 
2605 	LOG_DIS("move.%c [$r%u%s, $p%u\n",
2606 		    memsize_char(memsize),
2607 		    dc->op1,
2608 		    dc->postinc ? "+]" : "]",
2609 		    dc->op2);
2610 
2611 	cris_alu_m_alloc_temps(t);
2612 	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
2613 	cris_cc_mask(dc, 0);
2614 	if (dc->op2 == PR_CCS) {
2615 		cris_evaluate_flags(dc);
2616 		if (dc->tb_flags & U_FLAG) {
2617 			/* User space is not allowed to touch all flags.  */
2618 			tcg_gen_andi_tl(t[1], t[1], 0x39f);
2619 			tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2620 			tcg_gen_or_tl(t[1], t[0], t[1]);
2621 		}
2622 	}
2623 
2624 	t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2625 
2626 	do_postinc(dc, memsize);
2627 	cris_alu_m_free_temps(t);
2628 	return insn_len;
2629 }
2630 
dec_move_pm(DisasContext * dc)2631 static int dec_move_pm(DisasContext *dc)
2632 {
2633 	TCGv t0;
2634 	int memsize;
2635 
2636 	memsize = preg_sizes[dc->op2];
2637 
2638 	LOG_DIS("move.%c $p%u, [$r%u%s\n",
2639 		     memsize_char(memsize),
2640 		     dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2641 
2642 	/* prepare store. Address in T0, value in T1.  */
2643 	if (dc->op2 == PR_CCS)
2644 		cris_evaluate_flags(dc);
2645 	t0 = tcg_temp_new();
2646 	t_gen_mov_TN_preg(t0, dc->op2);
2647 	cris_flush_cc_state(dc);
2648 	gen_store(dc, cpu_R[dc->op1], t0, memsize);
2649 	tcg_temp_free(t0);
2650 
2651 	cris_cc_mask(dc, 0);
2652 	if (dc->postinc)
2653 		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2654 	return 2;
2655 }
2656 
dec_movem_mr(DisasContext * dc)2657 static int dec_movem_mr(DisasContext *dc)
2658 {
2659 	TCGv_i64 tmp[16];
2660         TCGv tmp32;
2661 	TCGv addr;
2662 	int i;
2663 	int nr = dc->op2 + 1;
2664 
2665 	LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2666 		    dc->postinc ? "+]" : "]", dc->op2);
2667 
2668 	addr = tcg_temp_new();
2669 	/* There are probably better ways of doing this.  */
2670 	cris_flush_cc_state(dc);
2671 	for (i = 0; i < (nr >> 1); i++) {
2672 		tmp[i] = tcg_temp_new_i64();
2673 		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2674 		gen_load64(dc, tmp[i], addr);
2675 	}
2676 	if (nr & 1) {
2677 		tmp32 = tcg_temp_new_i32();
2678 		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2679 		gen_load(dc, tmp32, addr, 4, 0);
2680 	} else
2681 		TCGV_UNUSED(tmp32);
2682 	tcg_temp_free(addr);
2683 
2684 	for (i = 0; i < (nr >> 1); i++) {
2685 		tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
2686 		tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2687 		tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2688 		tcg_temp_free_i64(tmp[i]);
2689 	}
2690 	if (nr & 1) {
2691 		tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2692 		tcg_temp_free(tmp32);
2693 	}
2694 
2695 	/* writeback the updated pointer value.  */
2696 	if (dc->postinc)
2697 		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2698 
2699 	/* gen_load might want to evaluate the previous insns flags.  */
2700 	cris_cc_mask(dc, 0);
2701 	return 2;
2702 }
2703 
dec_movem_rm(DisasContext * dc)2704 static int dec_movem_rm(DisasContext *dc)
2705 {
2706 	TCGv tmp;
2707 	TCGv addr;
2708 	int i;
2709 
2710 	LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2711 		     dc->postinc ? "+]" : "]");
2712 
2713 	cris_flush_cc_state(dc);
2714 
2715 	tmp = tcg_temp_new();
2716 	addr = tcg_temp_new();
2717 	tcg_gen_movi_tl(tmp, 4);
2718 	tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2719 	for (i = 0; i <= dc->op2; i++) {
2720 		/* Displace addr.  */
2721 		/* Perform the store.  */
2722 		gen_store(dc, addr, cpu_R[i], 4);
2723 		tcg_gen_add_tl(addr, addr, tmp);
2724 	}
2725 	if (dc->postinc)
2726 		tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2727 	cris_cc_mask(dc, 0);
2728 	tcg_temp_free(tmp);
2729 	tcg_temp_free(addr);
2730 	return 2;
2731 }
2732 
dec_move_rm(DisasContext * dc)2733 static int dec_move_rm(DisasContext *dc)
2734 {
2735 	int memsize;
2736 
2737 	memsize = memsize_zz(dc);
2738 
2739 	LOG_DIS("move.%c $r%u, [$r%u]\n",
2740 		     memsize_char(memsize), dc->op2, dc->op1);
2741 
2742 	/* prepare store.  */
2743 	cris_flush_cc_state(dc);
2744 	gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2745 
2746 	if (dc->postinc)
2747 		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2748 	cris_cc_mask(dc, 0);
2749 	return 2;
2750 }
2751 
dec_lapcq(DisasContext * dc)2752 static int dec_lapcq(DisasContext *dc)
2753 {
2754 	LOG_DIS("lapcq %x, $r%u\n",
2755 		    dc->pc + dc->op1*2, dc->op2);
2756 	cris_cc_mask(dc, 0);
2757 	tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2758 	return 2;
2759 }
2760 
dec_lapc_im(DisasContext * dc)2761 static int dec_lapc_im(DisasContext *dc)
2762 {
2763 	unsigned int rd;
2764 	int32_t imm;
2765 	int32_t pc;
2766 
2767 	rd = dc->op2;
2768 
2769 	cris_cc_mask(dc, 0);
2770 	imm = cris_fetch(dc, dc->pc + 2, 4, 0);
2771 	LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2772 
2773 	pc = dc->pc;
2774 	pc += imm;
2775 	tcg_gen_movi_tl(cpu_R[rd], pc);
2776 	return 6;
2777 }
2778 
2779 /* Jump to special reg.  */
dec_jump_p(DisasContext * dc)2780 static int dec_jump_p(DisasContext *dc)
2781 {
2782 	LOG_DIS("jump $p%u\n", dc->op2);
2783 
2784 	if (dc->op2 == PR_CCS)
2785 		cris_evaluate_flags(dc);
2786 	t_gen_mov_TN_preg(env_btarget, dc->op2);
2787 	/* rete will often have low bit set to indicate delayslot.  */
2788 	tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2789 	cris_cc_mask(dc, 0);
2790 	cris_prepare_jmp(dc, JMP_INDIRECT);
2791 	return 2;
2792 }
2793 
2794 /* Jump and save.  */
dec_jas_r(DisasContext * dc)2795 static int dec_jas_r(