xref: /openbmc/qemu/target/cris/translate.c (revision 1b1138ca)
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.1 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 "qemu/osdep.h"
27 #include "cpu.h"
28 #include "exec/exec-all.h"
29 #include "tcg/tcg-op.h"
30 #include "exec/helper-proto.h"
31 #include "mmu.h"
32 #include "exec/translator.h"
33 #include "crisv32-decode.h"
34 #include "qemu/qemu-print.h"
35 #include "exec/helper-gen.h"
36 #include "exec/log.h"
37 
38 #define HELPER_H "helper.h"
39 #include "exec/helper-info.c.inc"
40 #undef  HELPER_H
41 
42 
43 #define DISAS_CRIS 0
44 #if DISAS_CRIS
45 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46 #else
47 #  define LOG_DIS(...) do { } while (0)
48 #endif
49 
50 #define D(x)
51 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52 #define BUG_ON(x) ({if (x) BUG();})
53 
54 /*
55  * Target-specific is_jmp field values
56  */
57 /* Only pc was modified dynamically */
58 #define DISAS_JUMP          DISAS_TARGET_0
59 /* Cpu state was modified dynamically, including pc */
60 #define DISAS_UPDATE        DISAS_TARGET_1
61 /* Cpu state was modified dynamically, excluding pc -- use npc */
62 #define DISAS_UPDATE_NEXT   DISAS_TARGET_2
63 /* PC update for delayed branch, see cpustate_changed otherwise */
64 #define DISAS_DBRANCH       DISAS_TARGET_3
65 
66 /* Used by the decoder.  */
67 #define EXTRACT_FIELD(src, start, end) \
68             (((src) >> start) & ((1 << (end - start + 1)) - 1))
69 
70 #define CC_MASK_NZ 0xc
71 #define CC_MASK_NZV 0xe
72 #define CC_MASK_NZVC 0xf
73 #define CC_MASK_RNZV 0x10e
74 
75 static TCGv cpu_R[16];
76 static TCGv cpu_PR[16];
77 static TCGv cc_x;
78 static TCGv cc_src;
79 static TCGv cc_dest;
80 static TCGv cc_result;
81 static TCGv cc_op;
82 static TCGv cc_size;
83 static TCGv cc_mask;
84 
85 static TCGv env_btaken;
86 static TCGv env_btarget;
87 static TCGv env_pc;
88 
89 /* This is the state at translation time.  */
90 typedef struct DisasContext {
91     DisasContextBase base;
92 
93     CRISCPU *cpu;
94     target_ulong pc, ppc;
95     int mem_index;
96 
97     /* Decoder.  */
98         unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
99     uint32_t ir;
100     uint32_t opcode;
101     unsigned int op1;
102     unsigned int op2;
103     unsigned int zsize, zzsize;
104     unsigned int mode;
105     unsigned int postinc;
106 
107     unsigned int size;
108     unsigned int src;
109     unsigned int dst;
110     unsigned int cond;
111 
112     int update_cc;
113     int cc_op;
114     int cc_size;
115     uint32_t cc_mask;
116 
117     int cc_size_uptodate; /* -1 invalid or last written value.  */
118 
119     int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date.  */
120     int flags_uptodate; /* Whether or not $ccs is up-to-date.  */
121     int flags_x;
122 
123     int clear_x; /* Clear x after this insn?  */
124     int clear_prefix; /* Clear prefix after this insn?  */
125     int clear_locked_irq; /* Clear the irq lockout.  */
126     int cpustate_changed;
127     unsigned int tb_flags; /* tb dependent flags.  */
128 
129 #define JMP_NOJMP     0
130 #define JMP_DIRECT    1
131 #define JMP_DIRECT_CC 2
132 #define JMP_INDIRECT  3
133     int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */
134     uint32_t jmp_pc;
135 
136     int delayed_branch;
137 } DisasContext;
138 
gen_BUG(DisasContext * dc,const char * file,int line)139 static void gen_BUG(DisasContext *dc, const char *file, int line)
140 {
141     cpu_abort(CPU(dc->cpu), "%s:%d pc=%x\n", file, line, dc->pc);
142 }
143 
144 static const char * const regnames_v32[] =
145 {
146     "$r0", "$r1", "$r2", "$r3",
147     "$r4", "$r5", "$r6", "$r7",
148     "$r8", "$r9", "$r10", "$r11",
149     "$r12", "$r13", "$sp", "$acr",
150 };
151 
152 static const char * const pregnames_v32[] =
153 {
154     "$bz", "$vr", "$pid", "$srs",
155     "$wz", "$exs", "$eda", "$mof",
156     "$dz", "$ebp", "$erp", "$srp",
157     "$nrp", "$ccs", "$usp", "$spc",
158 };
159 
160 /* We need this table to handle preg-moves with implicit width.  */
161 static const int preg_sizes[] = {
162     1, /* bz.  */
163     1, /* vr.  */
164     4, /* pid.  */
165     1, /* srs.  */
166     2, /* wz.  */
167     4, 4, 4,
168     4, 4, 4, 4,
169     4, 4, 4, 4,
170 };
171 
172 #define t_gen_mov_TN_env(tn, member) \
173     tcg_gen_ld_tl(tn, tcg_env, offsetof(CPUCRISState, member))
174 #define t_gen_mov_env_TN(member, tn) \
175     tcg_gen_st_tl(tn, tcg_env, offsetof(CPUCRISState, member))
176 #define t_gen_movi_env_TN(member, c) \
177     t_gen_mov_env_TN(member, tcg_constant_tl(c))
178 
t_gen_mov_TN_preg(TCGv tn,int r)179 static inline void t_gen_mov_TN_preg(TCGv tn, int r)
180 {
181     assert(r >= 0 && r <= 15);
182     if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
183         tcg_gen_movi_tl(tn, 0);
184     } else if (r == PR_VR) {
185         tcg_gen_movi_tl(tn, 32);
186     } else {
187         tcg_gen_mov_tl(tn, cpu_PR[r]);
188     }
189 }
t_gen_mov_preg_TN(DisasContext * dc,int r,TCGv tn)190 static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
191 {
192     assert(r >= 0 && r <= 15);
193     if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
194         return;
195     } else if (r == PR_SRS) {
196         tcg_gen_andi_tl(cpu_PR[r], tn, 3);
197     } else {
198         if (r == PR_PID) {
199             gen_helper_tlb_flush_pid(tcg_env, tn);
200         }
201         if (dc->tb_flags & S_FLAG && r == PR_SPC) {
202             gen_helper_spc_write(tcg_env, tn);
203         } else if (r == PR_CCS) {
204             dc->cpustate_changed = 1;
205         }
206         tcg_gen_mov_tl(cpu_PR[r], tn);
207     }
208 }
209 
210 /* Sign extend at translation time.  */
sign_extend(unsigned int val,unsigned int width)211 static int sign_extend(unsigned int val, unsigned int width)
212 {
213     int sval;
214 
215     /* LSL.  */
216     val <<= 31 - width;
217     sval = val;
218     /* ASR.  */
219     sval >>= 31 - width;
220     return sval;
221 }
222 
cris_fetch(CPUCRISState * env,DisasContext * dc,uint32_t addr,unsigned int size,bool sign)223 static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
224                       unsigned int size, bool sign)
225 {
226     int r;
227 
228     switch (size) {
229     case 4:
230         r = translator_ldl(env, &dc->base, addr);
231         break;
232     case 2:
233         r = translator_lduw(env, &dc->base, addr);
234         if (sign) {
235             r = (int16_t)r;
236         }
237         break;
238     case 1:
239         r = translator_ldub(env, &dc->base, addr);
240         if (sign) {
241             r = (int8_t)r;
242         }
243         break;
244     default:
245         g_assert_not_reached();
246     }
247     return r;
248 }
249 
cris_lock_irq(DisasContext * dc)250 static void cris_lock_irq(DisasContext *dc)
251 {
252     dc->clear_locked_irq = 0;
253     t_gen_movi_env_TN(locked_irq, 1);
254 }
255 
t_gen_raise_exception(uint32_t index)256 static inline void t_gen_raise_exception(uint32_t index)
257 {
258     gen_helper_raise_exception(tcg_env, tcg_constant_i32(index));
259 }
260 
t_gen_lsl(TCGv d,TCGv a,TCGv b)261 static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
262 {
263     TCGv t0, t_31;
264 
265     t0 = tcg_temp_new();
266     t_31 = tcg_constant_tl(31);
267     tcg_gen_shl_tl(d, a, b);
268 
269     tcg_gen_sub_tl(t0, t_31, b);
270     tcg_gen_sar_tl(t0, t0, t_31);
271     tcg_gen_and_tl(t0, t0, d);
272     tcg_gen_xor_tl(d, d, t0);
273 }
274 
t_gen_lsr(TCGv d,TCGv a,TCGv b)275 static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
276 {
277     TCGv t0, t_31;
278 
279     t0 = tcg_temp_new();
280     t_31 = tcg_temp_new();
281     tcg_gen_shr_tl(d, a, b);
282 
283     tcg_gen_movi_tl(t_31, 31);
284     tcg_gen_sub_tl(t0, t_31, b);
285     tcg_gen_sar_tl(t0, t0, t_31);
286     tcg_gen_and_tl(t0, t0, d);
287     tcg_gen_xor_tl(d, d, t0);
288 }
289 
t_gen_asr(TCGv d,TCGv a,TCGv b)290 static void t_gen_asr(TCGv d, TCGv a, TCGv b)
291 {
292     TCGv t0, t_31;
293 
294     t0 = tcg_temp_new();
295     t_31 = tcg_temp_new();
296     tcg_gen_sar_tl(d, a, b);
297 
298     tcg_gen_movi_tl(t_31, 31);
299     tcg_gen_sub_tl(t0, t_31, b);
300     tcg_gen_sar_tl(t0, t0, t_31);
301     tcg_gen_or_tl(d, d, t0);
302 }
303 
t_gen_cris_dstep(TCGv d,TCGv a,TCGv b)304 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
305 {
306     TCGv t = tcg_temp_new();
307 
308     /*
309      * d <<= 1
310      * if (d >= s)
311      *    d -= s;
312      */
313     tcg_gen_shli_tl(d, a, 1);
314     tcg_gen_sub_tl(t, d, b);
315     tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d);
316 }
317 
t_gen_cris_mstep(TCGv d,TCGv a,TCGv b,TCGv ccs)318 static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
319 {
320     TCGv t;
321 
322     /*
323      * d <<= 1
324      * if (n)
325      *    d += s;
326      */
327     t = tcg_temp_new();
328     tcg_gen_shli_tl(d, a, 1);
329     tcg_gen_shli_tl(t, ccs, 31 - 3);
330     tcg_gen_sari_tl(t, t, 31);
331     tcg_gen_and_tl(t, t, b);
332     tcg_gen_add_tl(d, d, t);
333 }
334 
335 /* Extended arithmetic on CRIS.  */
t_gen_add_flag(TCGv d,int flag)336 static inline void t_gen_add_flag(TCGv d, int flag)
337 {
338     TCGv c;
339 
340     c = tcg_temp_new();
341     t_gen_mov_TN_preg(c, PR_CCS);
342     /* Propagate carry into d.  */
343     tcg_gen_andi_tl(c, c, 1 << flag);
344     if (flag) {
345         tcg_gen_shri_tl(c, c, flag);
346     }
347     tcg_gen_add_tl(d, d, c);
348 }
349 
t_gen_addx_carry(DisasContext * dc,TCGv d)350 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
351 {
352     if (dc->flags_x) {
353         TCGv c = tcg_temp_new();
354 
355         t_gen_mov_TN_preg(c, PR_CCS);
356         /* C flag is already at bit 0.  */
357         tcg_gen_andi_tl(c, c, C_FLAG);
358         tcg_gen_add_tl(d, d, c);
359     }
360 }
361 
t_gen_subx_carry(DisasContext * dc,TCGv d)362 static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
363 {
364     if (dc->flags_x) {
365         TCGv c = tcg_temp_new();
366 
367         t_gen_mov_TN_preg(c, PR_CCS);
368         /* C flag is already at bit 0.  */
369         tcg_gen_andi_tl(c, c, C_FLAG);
370         tcg_gen_sub_tl(d, d, c);
371     }
372 }
373 
374 /* Swap the two bytes within each half word of the s operand.
375    T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
t_gen_swapb(TCGv d,TCGv s)376 static inline void t_gen_swapb(TCGv d, TCGv s)
377 {
378     TCGv t, org_s;
379 
380     t = tcg_temp_new();
381     org_s = tcg_temp_new();
382 
383     /* d and s may refer to the same object.  */
384     tcg_gen_mov_tl(org_s, s);
385     tcg_gen_shli_tl(t, org_s, 8);
386     tcg_gen_andi_tl(d, t, 0xff00ff00);
387     tcg_gen_shri_tl(t, org_s, 8);
388     tcg_gen_andi_tl(t, t, 0x00ff00ff);
389     tcg_gen_or_tl(d, d, t);
390 }
391 
392 /* Swap the halfwords of the s operand.  */
t_gen_swapw(TCGv d,TCGv s)393 static inline void t_gen_swapw(TCGv d, TCGv s)
394 {
395     TCGv t;
396     /* d and s refer the same object.  */
397     t = tcg_temp_new();
398     tcg_gen_mov_tl(t, s);
399     tcg_gen_shli_tl(d, t, 16);
400     tcg_gen_shri_tl(t, t, 16);
401     tcg_gen_or_tl(d, d, t);
402 }
403 
404 /*
405  * Reverse the bits within each byte.
406  *
407  *  T0 = ((T0 << 7) & 0x80808080)
408  *     | ((T0 << 5) & 0x40404040)
409  *     | ((T0 << 3) & 0x20202020)
410  *     | ((T0 << 1) & 0x10101010)
411  *     | ((T0 >> 1) & 0x08080808)
412  *     | ((T0 >> 3) & 0x04040404)
413  *     | ((T0 >> 5) & 0x02020202)
414  *     | ((T0 >> 7) & 0x01010101);
415  */
t_gen_swapr(TCGv d,TCGv s)416 static void t_gen_swapr(TCGv d, TCGv s)
417 {
418     static const struct {
419         int shift; /* LSL when positive, LSR when negative.  */
420         uint32_t mask;
421     } bitrev[] = {
422         {7, 0x80808080},
423         {5, 0x40404040},
424         {3, 0x20202020},
425         {1, 0x10101010},
426         {-1, 0x08080808},
427         {-3, 0x04040404},
428         {-5, 0x02020202},
429         {-7, 0x01010101}
430     };
431     int i;
432     TCGv t, org_s;
433 
434     /* d and s refer the same object.  */
435     t = tcg_temp_new();
436     org_s = tcg_temp_new();
437     tcg_gen_mov_tl(org_s, s);
438 
439     tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
440     tcg_gen_andi_tl(d, t,  bitrev[0].mask);
441     for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
442         if (bitrev[i].shift >= 0) {
443             tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
444         } else {
445             tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
446         }
447         tcg_gen_andi_tl(t, t,  bitrev[i].mask);
448         tcg_gen_or_tl(d, d, t);
449     }
450 }
451 
use_goto_tb(DisasContext * dc,target_ulong dest)452 static bool use_goto_tb(DisasContext *dc, target_ulong dest)
453 {
454     return translator_use_goto_tb(&dc->base, dest);
455 }
456 
gen_goto_tb(DisasContext * dc,int n,target_ulong dest)457 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
458 {
459     if (use_goto_tb(dc, dest)) {
460         tcg_gen_goto_tb(n);
461         tcg_gen_movi_tl(env_pc, dest);
462         tcg_gen_exit_tb(dc->base.tb, n);
463     } else {
464         tcg_gen_movi_tl(env_pc, dest);
465         tcg_gen_lookup_and_goto_ptr();
466     }
467 }
468 
cris_clear_x_flag(DisasContext * dc)469 static inline void cris_clear_x_flag(DisasContext *dc)
470 {
471     if (dc->flags_x) {
472         dc->flags_uptodate = 0;
473     }
474     dc->flags_x = 0;
475 }
476 
cris_flush_cc_state(DisasContext * dc)477 static void cris_flush_cc_state(DisasContext *dc)
478 {
479     if (dc->cc_size_uptodate != dc->cc_size) {
480         tcg_gen_movi_tl(cc_size, dc->cc_size);
481         dc->cc_size_uptodate = dc->cc_size;
482     }
483     tcg_gen_movi_tl(cc_op, dc->cc_op);
484     tcg_gen_movi_tl(cc_mask, dc->cc_mask);
485 }
486 
cris_evaluate_flags(DisasContext * dc)487 static void cris_evaluate_flags(DisasContext *dc)
488 {
489     if (dc->flags_uptodate) {
490         return;
491     }
492 
493     cris_flush_cc_state(dc);
494 
495     switch (dc->cc_op) {
496     case CC_OP_MCP:
497         gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], tcg_env,
498                 cpu_PR[PR_CCS], cc_src,
499                 cc_dest, cc_result);
500         break;
501     case CC_OP_MULS:
502         gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], tcg_env,
503                 cpu_PR[PR_CCS], cc_result,
504                 cpu_PR[PR_MOF]);
505         break;
506     case CC_OP_MULU:
507         gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], tcg_env,
508                 cpu_PR[PR_CCS], cc_result,
509                 cpu_PR[PR_MOF]);
510         break;
511     case CC_OP_MOVE:
512     case CC_OP_AND:
513     case CC_OP_OR:
514     case CC_OP_XOR:
515     case CC_OP_ASR:
516     case CC_OP_LSR:
517     case CC_OP_LSL:
518         switch (dc->cc_size) {
519         case 4:
520             gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
521                     tcg_env, cpu_PR[PR_CCS], cc_result);
522             break;
523         case 2:
524             gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
525                     tcg_env, cpu_PR[PR_CCS], cc_result);
526             break;
527         default:
528             gen_helper_evaluate_flags(tcg_env);
529             break;
530         }
531         break;
532     case CC_OP_FLAGS:
533         /* live.  */
534         break;
535     case CC_OP_SUB:
536     case CC_OP_CMP:
537         if (dc->cc_size == 4) {
538             gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], tcg_env,
539                     cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
540         } else {
541             gen_helper_evaluate_flags(tcg_env);
542         }
543 
544         break;
545     default:
546         switch (dc->cc_size) {
547         case 4:
548             gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], tcg_env,
549                     cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
550             break;
551         default:
552             gen_helper_evaluate_flags(tcg_env);
553             break;
554         }
555         break;
556     }
557 
558     if (dc->flags_x) {
559         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
560     } else if (dc->cc_op == CC_OP_FLAGS) {
561         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
562     }
563     dc->flags_uptodate = 1;
564 }
565 
cris_cc_mask(DisasContext * dc,unsigned int mask)566 static void cris_cc_mask(DisasContext *dc, unsigned int mask)
567 {
568     uint32_t ovl;
569 
570     if (!mask) {
571         dc->update_cc = 0;
572         return;
573     }
574 
575     /* Check if we need to evaluate the condition codes due to
576        CC overlaying.  */
577     ovl = (dc->cc_mask ^ mask) & ~mask;
578     if (ovl) {
579         /* TODO: optimize this case. It trigs all the time.  */
580         cris_evaluate_flags(dc);
581     }
582     dc->cc_mask = mask;
583     dc->update_cc = 1;
584 }
585 
cris_update_cc_op(DisasContext * dc,int op,int size)586 static void cris_update_cc_op(DisasContext *dc, int op, int size)
587 {
588     dc->cc_op = op;
589     dc->cc_size = size;
590     dc->flags_uptodate = 0;
591 }
592 
cris_update_cc_x(DisasContext * dc)593 static inline void cris_update_cc_x(DisasContext *dc)
594 {
595     /* Save the x flag state at the time of the cc snapshot.  */
596     if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
597         return;
598     }
599     tcg_gen_movi_tl(cc_x, dc->flags_x);
600     dc->cc_x_uptodate = 2 | dc->flags_x;
601 }
602 
603 /* 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)604 static void cris_pre_alu_update_cc(DisasContext *dc, int op,
605                    TCGv dst, TCGv src, int size)
606 {
607     if (dc->update_cc) {
608         cris_update_cc_op(dc, op, size);
609         tcg_gen_mov_tl(cc_src, src);
610 
611         if (op != CC_OP_MOVE
612             && op != CC_OP_AND
613             && op != CC_OP_OR
614             && op != CC_OP_XOR
615             && op != CC_OP_ASR
616             && op != CC_OP_LSR
617             && op != CC_OP_LSL) {
618             tcg_gen_mov_tl(cc_dest, dst);
619         }
620 
621         cris_update_cc_x(dc);
622     }
623 }
624 
625 /* Update cc after executing ALU op. needs the result.  */
cris_update_result(DisasContext * dc,TCGv res)626 static inline void cris_update_result(DisasContext *dc, TCGv res)
627 {
628     if (dc->update_cc) {
629         tcg_gen_mov_tl(cc_result, res);
630     }
631 }
632 
633 /* 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)634 static void cris_alu_op_exec(DisasContext *dc, int op,
635                    TCGv dst, TCGv a, TCGv b, int size)
636 {
637     /* Emit the ALU insns.  */
638     switch (op) {
639     case CC_OP_ADD:
640         tcg_gen_add_tl(dst, a, b);
641         /* Extended arithmetic.  */
642         t_gen_addx_carry(dc, dst);
643         break;
644     case CC_OP_ADDC:
645         tcg_gen_add_tl(dst, a, b);
646         t_gen_add_flag(dst, 0); /* C_FLAG.  */
647         break;
648     case CC_OP_MCP:
649         tcg_gen_add_tl(dst, a, b);
650         t_gen_add_flag(dst, 8); /* R_FLAG.  */
651         break;
652     case CC_OP_SUB:
653         tcg_gen_sub_tl(dst, a, b);
654         /* Extended arithmetic.  */
655         t_gen_subx_carry(dc, dst);
656         break;
657     case CC_OP_MOVE:
658         tcg_gen_mov_tl(dst, b);
659         break;
660     case CC_OP_OR:
661         tcg_gen_or_tl(dst, a, b);
662         break;
663     case CC_OP_AND:
664         tcg_gen_and_tl(dst, a, b);
665         break;
666     case CC_OP_XOR:
667         tcg_gen_xor_tl(dst, a, b);
668         break;
669     case CC_OP_LSL:
670         t_gen_lsl(dst, a, b);
671         break;
672     case CC_OP_LSR:
673         t_gen_lsr(dst, a, b);
674         break;
675     case CC_OP_ASR:
676         t_gen_asr(dst, a, b);
677         break;
678     case CC_OP_NEG:
679         tcg_gen_neg_tl(dst, b);
680         /* Extended arithmetic.  */
681         t_gen_subx_carry(dc, dst);
682         break;
683     case CC_OP_LZ:
684         tcg_gen_clzi_tl(dst, b, TARGET_LONG_BITS);
685         break;
686     case CC_OP_MULS:
687         tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
688         break;
689     case CC_OP_MULU:
690         tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b);
691         break;
692     case CC_OP_DSTEP:
693         t_gen_cris_dstep(dst, a, b);
694         break;
695     case CC_OP_MSTEP:
696         t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
697         break;
698     case CC_OP_BOUND:
699         tcg_gen_movcond_tl(TCG_COND_LEU, dst, a, b, a, b);
700         break;
701     case CC_OP_CMP:
702         tcg_gen_sub_tl(dst, a, b);
703         /* Extended arithmetic.  */
704         t_gen_subx_carry(dc, dst);
705         break;
706     default:
707         qemu_log_mask(LOG_GUEST_ERROR, "illegal ALU op.\n");
708         BUG();
709         break;
710     }
711 
712     if (size == 1) {
713         tcg_gen_andi_tl(dst, dst, 0xff);
714     } else if (size == 2) {
715         tcg_gen_andi_tl(dst, dst, 0xffff);
716     }
717 }
718 
cris_alu(DisasContext * dc,int op,TCGv d,TCGv op_a,TCGv op_b,int size)719 static void cris_alu(DisasContext *dc, int op,
720                    TCGv d, TCGv op_a, TCGv op_b, int size)
721 {
722     TCGv tmp;
723     int writeback;
724 
725     writeback = 1;
726 
727     if (op == CC_OP_CMP) {
728         tmp = tcg_temp_new();
729         writeback = 0;
730     } else if (size == 4) {
731         tmp = d;
732         writeback = 0;
733     } else {
734         tmp = tcg_temp_new();
735     }
736 
737 
738     cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
739     cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
740     cris_update_result(dc, tmp);
741 
742     /* Writeback.  */
743     if (writeback) {
744         if (size == 1) {
745             tcg_gen_andi_tl(d, d, ~0xff);
746         } else {
747             tcg_gen_andi_tl(d, d, ~0xffff);
748         }
749         tcg_gen_or_tl(d, d, tmp);
750     }
751 }
752 
arith_cc(DisasContext * dc)753 static int arith_cc(DisasContext *dc)
754 {
755     if (dc->update_cc) {
756         switch (dc->cc_op) {
757         case CC_OP_ADDC: return 1;
758         case CC_OP_ADD: return 1;
759         case CC_OP_SUB: return 1;
760         case CC_OP_DSTEP: return 1;
761         case CC_OP_LSL: return 1;
762         case CC_OP_LSR: return 1;
763         case CC_OP_ASR: return 1;
764         case CC_OP_CMP: return 1;
765         case CC_OP_NEG: return 1;
766         case CC_OP_OR: return 1;
767         case CC_OP_AND: return 1;
768         case CC_OP_XOR: return 1;
769         case CC_OP_MULU: return 1;
770         case CC_OP_MULS: return 1;
771         default:
772             return 0;
773         }
774     }
775     return 0;
776 }
777 
gen_tst_cc(DisasContext * dc,TCGv cc,int cond)778 static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
779 {
780     int arith_opt, move_opt;
781 
782     /* TODO: optimize more condition codes.  */
783 
784     /*
785      * If the flags are live, we've gotta look into the bits of CCS.
786      * Otherwise, if we just did an arithmetic operation we try to
787      * evaluate the condition code faster.
788      *
789      * When this function is done, T0 should be non-zero if the condition
790      * code is true.
791      */
792     arith_opt = arith_cc(dc) && !dc->flags_uptodate;
793     move_opt = (dc->cc_op == CC_OP_MOVE);
794     switch (cond) {
795     case CC_EQ:
796         if ((arith_opt || move_opt)
797                 && dc->cc_x_uptodate != (2 | X_FLAG)) {
798             tcg_gen_setcondi_tl(TCG_COND_EQ, cc, cc_result, 0);
799         } else {
800             cris_evaluate_flags(dc);
801             tcg_gen_andi_tl(cc,
802                     cpu_PR[PR_CCS], Z_FLAG);
803         }
804         break;
805     case CC_NE:
806         if ((arith_opt || move_opt)
807                 && dc->cc_x_uptodate != (2 | X_FLAG)) {
808             tcg_gen_mov_tl(cc, cc_result);
809         } else {
810             cris_evaluate_flags(dc);
811             tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
812                     Z_FLAG);
813             tcg_gen_andi_tl(cc, cc, Z_FLAG);
814         }
815         break;
816     case CC_CS:
817         cris_evaluate_flags(dc);
818         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
819         break;
820     case CC_CC:
821         cris_evaluate_flags(dc);
822         tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
823         tcg_gen_andi_tl(cc, cc, C_FLAG);
824         break;
825     case CC_VS:
826         cris_evaluate_flags(dc);
827         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
828         break;
829     case CC_VC:
830         cris_evaluate_flags(dc);
831         tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
832                 V_FLAG);
833         tcg_gen_andi_tl(cc, cc, V_FLAG);
834         break;
835     case CC_PL:
836         if (arith_opt || move_opt) {
837             int bits = 31;
838 
839             if (dc->cc_size == 1) {
840                 bits = 7;
841             } else if (dc->cc_size == 2) {
842                 bits = 15;
843             }
844 
845             tcg_gen_shri_tl(cc, cc_result, bits);
846             tcg_gen_xori_tl(cc, cc, 1);
847         } else {
848             cris_evaluate_flags(dc);
849             tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
850                     N_FLAG);
851             tcg_gen_andi_tl(cc, cc, N_FLAG);
852         }
853         break;
854     case CC_MI:
855         if (arith_opt || move_opt) {
856             int bits = 31;
857 
858             if (dc->cc_size == 1) {
859                 bits = 7;
860             } else if (dc->cc_size == 2) {
861                 bits = 15;
862             }
863 
864             tcg_gen_shri_tl(cc, cc_result, bits);
865             tcg_gen_andi_tl(cc, cc, 1);
866         } else {
867             cris_evaluate_flags(dc);
868             tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
869                     N_FLAG);
870         }
871         break;
872     case CC_LS:
873         cris_evaluate_flags(dc);
874         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
875                 C_FLAG | Z_FLAG);
876         break;
877     case CC_HI:
878         cris_evaluate_flags(dc);
879         {
880             TCGv tmp;
881 
882             tmp = tcg_temp_new();
883             tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
884                     C_FLAG | Z_FLAG);
885             /* Overlay the C flag on top of the Z.  */
886             tcg_gen_shli_tl(cc, tmp, 2);
887             tcg_gen_and_tl(cc, tmp, cc);
888             tcg_gen_andi_tl(cc, cc, Z_FLAG);
889         }
890         break;
891     case CC_GE:
892         cris_evaluate_flags(dc);
893         /* Overlay the V flag on top of the N.  */
894         tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
895         tcg_gen_xor_tl(cc,
896                 cpu_PR[PR_CCS], cc);
897         tcg_gen_andi_tl(cc, cc, N_FLAG);
898         tcg_gen_xori_tl(cc, cc, N_FLAG);
899         break;
900     case CC_LT:
901         cris_evaluate_flags(dc);
902         /* Overlay the V flag on top of the N.  */
903         tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
904         tcg_gen_xor_tl(cc,
905                 cpu_PR[PR_CCS], cc);
906         tcg_gen_andi_tl(cc, cc, N_FLAG);
907         break;
908     case CC_GT:
909         cris_evaluate_flags(dc);
910         {
911             TCGv n, z;
912 
913             n = tcg_temp_new();
914             z = tcg_temp_new();
915 
916             /* To avoid a shift we overlay everything on
917                    the V flag.  */
918             tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
919             tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
920             /* invert Z.  */
921             tcg_gen_xori_tl(z, z, 2);
922 
923             tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
924             tcg_gen_xori_tl(n, n, 2);
925             tcg_gen_and_tl(cc, z, n);
926             tcg_gen_andi_tl(cc, cc, 2);
927         }
928         break;
929     case CC_LE:
930         cris_evaluate_flags(dc);
931         {
932             TCGv n, z;
933 
934             n = tcg_temp_new();
935             z = tcg_temp_new();
936 
937             /* To avoid a shift we overlay everything on
938                    the V flag.  */
939             tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
940             tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
941 
942             tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
943             tcg_gen_or_tl(cc, z, n);
944             tcg_gen_andi_tl(cc, cc, 2);
945         }
946         break;
947     case CC_P:
948         cris_evaluate_flags(dc);
949         tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
950         break;
951     case CC_A:
952         tcg_gen_movi_tl(cc, 1);
953         break;
954     default:
955         BUG();
956         break;
957     };
958 }
959 
cris_store_direct_jmp(DisasContext * dc)960 static void cris_store_direct_jmp(DisasContext *dc)
961 {
962     /* Store the direct jmp state into the cpu-state.  */
963     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
964         if (dc->jmp == JMP_DIRECT) {
965             tcg_gen_movi_tl(env_btaken, 1);
966         }
967         tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
968         dc->jmp = JMP_INDIRECT;
969     }
970 }
971 
cris_prepare_cc_branch(DisasContext * dc,int offset,int cond)972 static void cris_prepare_cc_branch (DisasContext *dc,
973                     int offset, int cond)
974 {
975     /* This helps us re-schedule the micro-code to insns in delay-slots
976        before the actual jump.  */
977     dc->delayed_branch = 2;
978     dc->jmp = JMP_DIRECT_CC;
979     dc->jmp_pc = dc->pc + offset;
980 
981     gen_tst_cc(dc, env_btaken, cond);
982     tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
983 }
984 
985 
986 /* jumps, when the dest is in a live reg for example. Direct should be set
987    when the dest addr is constant to allow tb chaining.  */
cris_prepare_jmp(DisasContext * dc,unsigned int type)988 static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
989 {
990     /* This helps us re-schedule the micro-code to insns in delay-slots
991        before the actual jump.  */
992     dc->delayed_branch = 2;
993     dc->jmp = type;
994     if (type == JMP_INDIRECT) {
995         tcg_gen_movi_tl(env_btaken, 1);
996     }
997 }
998 
gen_load64(DisasContext * dc,TCGv_i64 dst,TCGv addr)999 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
1000 {
1001     /* If we get a fault on a delayslot we must keep the jmp state in
1002        the cpu-state to be able to re-execute the jmp.  */
1003     if (dc->delayed_branch == 1) {
1004         cris_store_direct_jmp(dc);
1005     }
1006 
1007     tcg_gen_qemu_ld_i64(dst, addr, dc->mem_index, MO_TEUQ);
1008 }
1009 
gen_load(DisasContext * dc,TCGv dst,TCGv addr,unsigned int size,int sign)1010 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
1011              unsigned int size, int sign)
1012 {
1013     /* If we get a fault on a delayslot we must keep the jmp state in
1014        the cpu-state to be able to re-execute the jmp.  */
1015     if (dc->delayed_branch == 1) {
1016         cris_store_direct_jmp(dc);
1017     }
1018 
1019     tcg_gen_qemu_ld_tl(dst, addr, dc->mem_index,
1020                        MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
1021 }
1022 
gen_store(DisasContext * dc,TCGv addr,TCGv val,unsigned int size)1023 static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
1024                unsigned int size)
1025 {
1026     /* If we get a fault on a delayslot we must keep the jmp state in
1027        the cpu-state to be able to re-execute the jmp.  */
1028     if (dc->delayed_branch == 1) {
1029         cris_store_direct_jmp(dc);
1030     }
1031 
1032 
1033     /* Conditional writes. We only support the kind were X and P are known
1034        at translation time.  */
1035     if (dc->flags_x && (dc->tb_flags & P_FLAG)) {
1036         dc->postinc = 0;
1037         cris_evaluate_flags(dc);
1038         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
1039         return;
1040     }
1041 
1042     tcg_gen_qemu_st_tl(val, addr, dc->mem_index, MO_TE + ctz32(size));
1043 
1044     if (dc->flags_x) {
1045         cris_evaluate_flags(dc);
1046         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
1047     }
1048 }
1049 
t_gen_sext(TCGv d,TCGv s,int size)1050 static inline void t_gen_sext(TCGv d, TCGv s, int size)
1051 {
1052     if (size == 1) {
1053         tcg_gen_ext8s_i32(d, s);
1054     } else if (size == 2) {
1055         tcg_gen_ext16s_i32(d, s);
1056     } else {
1057         tcg_gen_mov_tl(d, s);
1058     }
1059 }
1060 
t_gen_zext(TCGv d,TCGv s,int size)1061 static inline void t_gen_zext(TCGv d, TCGv s, int size)
1062 {
1063     if (size == 1) {
1064         tcg_gen_ext8u_i32(d, s);
1065     } else if (size == 2) {
1066         tcg_gen_ext16u_i32(d, s);
1067     } else {
1068         tcg_gen_mov_tl(d, s);
1069     }
1070 }
1071 
1072 #if DISAS_CRIS
memsize_char(int size)1073 static char memsize_char(int size)
1074 {
1075     switch (size) {
1076     case 1: return 'b';
1077     case 2: return 'w';
1078     case 4: return 'd';
1079     default:
1080         return 'x';
1081     }
1082 }
1083 #endif
1084 
memsize_z(DisasContext * dc)1085 static inline unsigned int memsize_z(DisasContext *dc)
1086 {
1087     return dc->zsize + 1;
1088 }
1089 
memsize_zz(DisasContext * dc)1090 static inline unsigned int memsize_zz(DisasContext *dc)
1091 {
1092     switch (dc->zzsize) {
1093     case 0: return 1;
1094     case 1: return 2;
1095     default:
1096         return 4;
1097     }
1098 }
1099 
do_postinc(DisasContext * dc,int size)1100 static inline void do_postinc (DisasContext *dc, int size)
1101 {
1102     if (dc->postinc) {
1103         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
1104     }
1105 }
1106 
dec_prep_move_r(DisasContext * dc,int rs,int rd,int size,int s_ext,TCGv dst)1107 static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
1108                    int size, int s_ext, TCGv dst)
1109 {
1110     if (s_ext) {
1111         t_gen_sext(dst, cpu_R[rs], size);
1112     } else {
1113         t_gen_zext(dst, cpu_R[rs], size);
1114     }
1115 }
1116 
1117 /* Prepare T0 and T1 for a register alu operation.
1118    s_ext decides if the operand1 should be sign-extended or zero-extended when
1119    needed.  */
dec_prep_alu_r(DisasContext * dc,int rs,int rd,int size,int s_ext,TCGv dst,TCGv src)1120 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1121               int size, int s_ext, TCGv dst, TCGv src)
1122 {
1123     dec_prep_move_r(dc, rs, rd, size, s_ext, src);
1124 
1125     if (s_ext) {
1126         t_gen_sext(dst, cpu_R[rd], size);
1127     } else {
1128         t_gen_zext(dst, cpu_R[rd], size);
1129     }
1130 }
1131 
dec_prep_move_m(CPUCRISState * env,DisasContext * dc,int s_ext,int memsize,TCGv dst)1132 static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
1133                            int s_ext, int memsize, TCGv dst)
1134 {
1135     unsigned int rs;
1136     uint32_t imm;
1137     int is_imm;
1138     int insn_len = 2;
1139 
1140     rs = dc->op1;
1141     is_imm = rs == 15 && dc->postinc;
1142 
1143     /* Load [$rs] onto T1.  */
1144     if (is_imm) {
1145         insn_len = 2 + memsize;
1146         if (memsize == 1) {
1147             insn_len++;
1148         }
1149 
1150         imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
1151         tcg_gen_movi_tl(dst, imm);
1152         dc->postinc = 0;
1153     } else {
1154         cris_flush_cc_state(dc);
1155         gen_load(dc, dst, cpu_R[rs], memsize, 0);
1156         if (s_ext) {
1157             t_gen_sext(dst, dst, memsize);
1158         } else {
1159             t_gen_zext(dst, dst, memsize);
1160         }
1161     }
1162     return insn_len;
1163 }
1164 
1165 /* Prepare T0 and T1 for a memory + alu operation.
1166    s_ext decides if the operand1 should be sign-extended or zero-extended when
1167    needed.  */
dec_prep_alu_m(CPUCRISState * env,DisasContext * dc,int s_ext,int memsize,TCGv dst,TCGv src)1168 static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
1169                           int s_ext, int memsize, TCGv dst, TCGv src)
1170 {
1171     int insn_len;
1172 
1173     insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
1174     tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
1175     return insn_len;
1176 }
1177 
1178 #if DISAS_CRIS
cc_name(int cc)1179 static const char *cc_name(int cc)
1180 {
1181     static const char * const cc_names[16] = {
1182         "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
1183         "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
1184     };
1185     assert(cc < 16);
1186     return cc_names[cc];
1187 }
1188 #endif
1189 
1190 /* Start of insn decoders.  */
1191 
dec_bccq(CPUCRISState * env,DisasContext * dc)1192 static int dec_bccq(CPUCRISState *env, DisasContext *dc)
1193 {
1194     int32_t offset;
1195     int sign;
1196     uint32_t cond = dc->op2;
1197 
1198     offset = EXTRACT_FIELD(dc->ir, 1, 7);
1199     sign = EXTRACT_FIELD(dc->ir, 0, 0);
1200 
1201     offset *= 2;
1202     offset |= sign << 8;
1203     offset = sign_extend(offset, 8);
1204 
1205     LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
1206 
1207     /* op2 holds the condition-code.  */
1208     cris_cc_mask(dc, 0);
1209     cris_prepare_cc_branch(dc, offset, cond);
1210     return 2;
1211 }
dec_addoq(CPUCRISState * env,DisasContext * dc)1212 static int dec_addoq(CPUCRISState *env, DisasContext *dc)
1213 {
1214     int32_t imm;
1215 
1216     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1217     imm = sign_extend(dc->op1, 7);
1218 
1219     LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
1220     cris_cc_mask(dc, 0);
1221     /* Fetch register operand,  */
1222     tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1223 
1224     return 2;
1225 }
dec_addq(CPUCRISState * env,DisasContext * dc)1226 static int dec_addq(CPUCRISState *env, DisasContext *dc)
1227 {
1228     TCGv c;
1229     LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
1230 
1231     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1232 
1233     cris_cc_mask(dc, CC_MASK_NZVC);
1234 
1235     c = tcg_constant_tl(dc->op1);
1236     cris_alu(dc, CC_OP_ADD,
1237             cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
1238     return 2;
1239 }
dec_moveq(CPUCRISState * env,DisasContext * dc)1240 static int dec_moveq(CPUCRISState *env, DisasContext *dc)
1241 {
1242     uint32_t imm;
1243 
1244     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1245     imm = sign_extend(dc->op1, 5);
1246     LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
1247 
1248     tcg_gen_movi_tl(cpu_R[dc->op2], imm);
1249     return 2;
1250 }
dec_subq(CPUCRISState * env,DisasContext * dc)1251 static int dec_subq(CPUCRISState *env, DisasContext *dc)
1252 {
1253     TCGv c;
1254     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1255 
1256     LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
1257 
1258     cris_cc_mask(dc, CC_MASK_NZVC);
1259     c = tcg_constant_tl(dc->op1);
1260     cris_alu(dc, CC_OP_SUB,
1261             cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
1262     return 2;
1263 }
dec_cmpq(CPUCRISState * env,DisasContext * dc)1264 static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
1265 {
1266     uint32_t imm;
1267     TCGv c;
1268     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1269     imm = sign_extend(dc->op1, 5);
1270 
1271     LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
1272     cris_cc_mask(dc, CC_MASK_NZVC);
1273 
1274     c = tcg_constant_tl(imm);
1275     cris_alu(dc, CC_OP_CMP,
1276             cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
1277     return 2;
1278 }
dec_andq(CPUCRISState * env,DisasContext * dc)1279 static int dec_andq(CPUCRISState *env, DisasContext *dc)
1280 {
1281     uint32_t imm;
1282     TCGv c;
1283     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1284     imm = sign_extend(dc->op1, 5);
1285 
1286     LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
1287     cris_cc_mask(dc, CC_MASK_NZ);
1288 
1289     c = tcg_constant_tl(imm);
1290     cris_alu(dc, CC_OP_AND,
1291             cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
1292     return 2;
1293 }
dec_orq(CPUCRISState * env,DisasContext * dc)1294 static int dec_orq(CPUCRISState *env, DisasContext *dc)
1295 {
1296     uint32_t imm;
1297     TCGv c;
1298     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
1299     imm = sign_extend(dc->op1, 5);
1300     LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
1301     cris_cc_mask(dc, CC_MASK_NZ);
1302 
1303     c = tcg_constant_tl(imm);
1304     cris_alu(dc, CC_OP_OR,
1305             cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
1306     return 2;
1307 }
dec_btstq(CPUCRISState * env,DisasContext * dc)1308 static int dec_btstq(CPUCRISState *env, DisasContext *dc)
1309 {
1310     TCGv c;
1311     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1312     LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
1313 
1314     cris_cc_mask(dc, CC_MASK_NZ);
1315     c = tcg_constant_tl(dc->op1);
1316     cris_evaluate_flags(dc);
1317     gen_helper_btst(cpu_PR[PR_CCS], tcg_env, cpu_R[dc->op2],
1318             c, cpu_PR[PR_CCS]);
1319     cris_alu(dc, CC_OP_MOVE,
1320          cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1321     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1322     dc->flags_uptodate = 1;
1323     return 2;
1324 }
dec_asrq(CPUCRISState * env,DisasContext * dc)1325 static int dec_asrq(CPUCRISState *env, DisasContext *dc)
1326 {
1327     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1328     LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
1329     cris_cc_mask(dc, CC_MASK_NZ);
1330 
1331     tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1332     cris_alu(dc, CC_OP_MOVE,
1333             cpu_R[dc->op2],
1334             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1335     return 2;
1336 }
dec_lslq(CPUCRISState * env,DisasContext * dc)1337 static int dec_lslq(CPUCRISState *env, DisasContext *dc)
1338 {
1339     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1340     LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
1341 
1342     cris_cc_mask(dc, CC_MASK_NZ);
1343 
1344     tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1345 
1346     cris_alu(dc, CC_OP_MOVE,
1347             cpu_R[dc->op2],
1348             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1349     return 2;
1350 }
dec_lsrq(CPUCRISState * env,DisasContext * dc)1351 static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
1352 {
1353     dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1354     LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
1355 
1356     cris_cc_mask(dc, CC_MASK_NZ);
1357 
1358     tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
1359     cris_alu(dc, CC_OP_MOVE,
1360             cpu_R[dc->op2],
1361             cpu_R[dc->op2], cpu_R[dc->op2], 4);
1362     return 2;
1363 }
1364 
dec_move_r(CPUCRISState * env,DisasContext * dc)1365 static int dec_move_r(CPUCRISState *env, DisasContext *dc)
1366 {
1367     int size = memsize_zz(dc);
1368 
1369     LOG_DIS("move.%c $r%u, $r%u\n",
1370             memsize_char(size), dc->op1, dc->op2);
1371 
1372     cris_cc_mask(dc, CC_MASK_NZ);
1373     if (size == 4) {
1374         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
1375         cris_cc_mask(dc, CC_MASK_NZ);
1376         cris_update_cc_op(dc, CC_OP_MOVE, 4);
1377         cris_update_cc_x(dc);
1378         cris_update_result(dc, cpu_R[dc->op2]);
1379     } else {
1380         TCGv t0;
1381 
1382         t0 = tcg_temp_new();
1383         dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1384         cris_alu(dc, CC_OP_MOVE,
1385              cpu_R[dc->op2],
1386              cpu_R[dc->op2], t0, size);
1387     }
1388     return 2;
1389 }
1390 
dec_scc_r(CPUCRISState * env,DisasContext * dc)1391 static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
1392 {
1393     int cond = dc->op2;
1394 
1395     LOG_DIS("s%s $r%u\n",
1396             cc_name(cond), dc->op1);
1397 
1398     gen_tst_cc(dc, cpu_R[dc->op1], cond);
1399     tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0);
1400 
1401     cris_cc_mask(dc, 0);
1402     return 2;
1403 }
1404 
cris_alu_alloc_temps(DisasContext * dc,int size,TCGv * t)1405 static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
1406 {
1407     if (size == 4) {
1408         t[0] = cpu_R[dc->op2];
1409         t[1] = cpu_R[dc->op1];
1410     } else {
1411         t[0] = tcg_temp_new();
1412         t[1] = tcg_temp_new();
1413     }
1414 }
1415 
dec_and_r(CPUCRISState * env,DisasContext * dc)1416 static int dec_and_r(CPUCRISState *env, DisasContext *dc)
1417 {
1418     TCGv t[2];
1419     int size = memsize_zz(dc);
1420 
1421     LOG_DIS("and.%c $r%u, $r%u\n",
1422             memsize_char(size), dc->op1, dc->op2);
1423 
1424     cris_cc_mask(dc, CC_MASK_NZ);
1425 
1426     cris_alu_alloc_temps(dc, size, t);
1427     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1428     cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
1429     return 2;
1430 }
1431 
dec_lz_r(CPUCRISState * env,DisasContext * dc)1432 static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
1433 {
1434     TCGv t0;
1435     LOG_DIS("lz $r%u, $r%u\n",
1436             dc->op1, dc->op2);
1437     cris_cc_mask(dc, CC_MASK_NZ);
1438     t0 = tcg_temp_new();
1439     dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
1440     cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1441     return 2;
1442 }
1443 
dec_lsl_r(CPUCRISState * env,DisasContext * dc)1444 static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
1445 {
1446     TCGv t[2];
1447     int size = memsize_zz(dc);
1448 
1449     LOG_DIS("lsl.%c $r%u, $r%u\n",
1450             memsize_char(size), dc->op1, dc->op2);
1451 
1452     cris_cc_mask(dc, CC_MASK_NZ);
1453     cris_alu_alloc_temps(dc, size, t);
1454     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1455     tcg_gen_andi_tl(t[1], t[1], 63);
1456     cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
1457     return 2;
1458 }
1459 
dec_lsr_r(CPUCRISState * env,DisasContext * dc)1460 static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
1461 {
1462     TCGv t[2];
1463     int size = memsize_zz(dc);
1464 
1465     LOG_DIS("lsr.%c $r%u, $r%u\n",
1466             memsize_char(size), dc->op1, dc->op2);
1467 
1468     cris_cc_mask(dc, CC_MASK_NZ);
1469     cris_alu_alloc_temps(dc, size, t);
1470     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1471     tcg_gen_andi_tl(t[1], t[1], 63);
1472     cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
1473     return 2;
1474 }
1475 
dec_asr_r(CPUCRISState * env,DisasContext * dc)1476 static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
1477 {
1478     TCGv t[2];
1479     int size = memsize_zz(dc);
1480 
1481     LOG_DIS("asr.%c $r%u, $r%u\n",
1482             memsize_char(size), dc->op1, dc->op2);
1483 
1484     cris_cc_mask(dc, CC_MASK_NZ);
1485     cris_alu_alloc_temps(dc, size, t);
1486     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1487     tcg_gen_andi_tl(t[1], t[1], 63);
1488     cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
1489     return 2;
1490 }
1491 
dec_muls_r(CPUCRISState * env,DisasContext * dc)1492 static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
1493 {
1494     TCGv t[2];
1495     int size = memsize_zz(dc);
1496 
1497     LOG_DIS("muls.%c $r%u, $r%u\n",
1498             memsize_char(size), dc->op1, dc->op2);
1499     cris_cc_mask(dc, CC_MASK_NZV);
1500     cris_alu_alloc_temps(dc, size, t);
1501     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
1502 
1503     cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
1504     return 2;
1505 }
1506 
dec_mulu_r(CPUCRISState * env,DisasContext * dc)1507 static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
1508 {
1509     TCGv t[2];
1510     int size = memsize_zz(dc);
1511 
1512     LOG_DIS("mulu.%c $r%u, $r%u\n",
1513             memsize_char(size), dc->op1, dc->op2);
1514     cris_cc_mask(dc, CC_MASK_NZV);
1515     cris_alu_alloc_temps(dc, size, t);
1516     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1517 
1518     cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
1519     return 2;
1520 }
1521 
1522 
dec_dstep_r(CPUCRISState * env,DisasContext * dc)1523 static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
1524 {
1525     LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
1526     cris_cc_mask(dc, CC_MASK_NZ);
1527     cris_alu(dc, CC_OP_DSTEP,
1528             cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1529     return 2;
1530 }
1531 
dec_xor_r(CPUCRISState * env,DisasContext * dc)1532 static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
1533 {
1534     TCGv t[2];
1535     int size = memsize_zz(dc);
1536     LOG_DIS("xor.%c $r%u, $r%u\n",
1537             memsize_char(size), dc->op1, dc->op2);
1538     BUG_ON(size != 4); /* xor is dword.  */
1539     cris_cc_mask(dc, CC_MASK_NZ);
1540     cris_alu_alloc_temps(dc, size, t);
1541     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1542 
1543     cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
1544     return 2;
1545 }
1546 
dec_bound_r(CPUCRISState * env,DisasContext * dc)1547 static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
1548 {
1549     TCGv l0;
1550     int size = memsize_zz(dc);
1551     LOG_DIS("bound.%c $r%u, $r%u\n",
1552             memsize_char(size), dc->op1, dc->op2);
1553     cris_cc_mask(dc, CC_MASK_NZ);
1554     l0 = tcg_temp_new();
1555     dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
1556     cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
1557     return 2;
1558 }
1559 
dec_cmp_r(CPUCRISState * env,DisasContext * dc)1560 static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
1561 {
1562     TCGv t[2];
1563     int size = memsize_zz(dc);
1564     LOG_DIS("cmp.%c $r%u, $r%u\n",
1565             memsize_char(size), dc->op1, dc->op2);
1566     cris_cc_mask(dc, CC_MASK_NZVC);
1567     cris_alu_alloc_temps(dc, size, t);
1568     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1569 
1570     cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
1571     return 2;
1572 }
1573 
dec_abs_r(CPUCRISState * env,DisasContext * dc)1574 static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
1575 {
1576     LOG_DIS("abs $r%u, $r%u\n",
1577             dc->op1, dc->op2);
1578     cris_cc_mask(dc, CC_MASK_NZ);
1579 
1580     tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
1581     cris_alu(dc, CC_OP_MOVE,
1582             cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1583     return 2;
1584 }
1585 
dec_add_r(CPUCRISState * env,DisasContext * dc)1586 static int dec_add_r(CPUCRISState *env, DisasContext *dc)
1587 {
1588     TCGv t[2];
1589     int size = memsize_zz(dc);
1590     LOG_DIS("add.%c $r%u, $r%u\n",
1591             memsize_char(size), dc->op1, dc->op2);
1592     cris_cc_mask(dc, CC_MASK_NZVC);
1593     cris_alu_alloc_temps(dc, size, t);
1594     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1595 
1596     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
1597     return 2;
1598 }
1599 
dec_addc_r(CPUCRISState * env,DisasContext * dc)1600 static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
1601 {
1602     LOG_DIS("addc $r%u, $r%u\n",
1603             dc->op1, dc->op2);
1604     cris_evaluate_flags(dc);
1605 
1606     /* Set for this insn.  */
1607     dc->flags_x = X_FLAG;
1608 
1609     cris_cc_mask(dc, CC_MASK_NZVC);
1610     cris_alu(dc, CC_OP_ADDC,
1611          cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
1612     return 2;
1613 }
1614 
dec_mcp_r(CPUCRISState * env,DisasContext * dc)1615 static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
1616 {
1617     LOG_DIS("mcp $p%u, $r%u\n",
1618              dc->op2, dc->op1);
1619     cris_evaluate_flags(dc);
1620     cris_cc_mask(dc, CC_MASK_RNZV);
1621     cris_alu(dc, CC_OP_MCP,
1622             cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
1623     return 2;
1624 }
1625 
1626 #if DISAS_CRIS
swapmode_name(int mode,char * modename)1627 static char * swapmode_name(int mode, char *modename) {
1628     int i = 0;
1629     if (mode & 8) {
1630         modename[i++] = 'n';
1631     }
1632     if (mode & 4) {
1633         modename[i++] = 'w';
1634     }
1635     if (mode & 2) {
1636         modename[i++] = 'b';
1637     }
1638     if (mode & 1) {
1639         modename[i++] = 'r';
1640     }
1641     modename[i++] = 0;
1642     return modename;
1643 }
1644 #endif
1645 
dec_swap_r(CPUCRISState * env,DisasContext * dc)1646 static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
1647 {
1648     TCGv t0;
1649 #if DISAS_CRIS
1650     char modename[4];
1651 #endif
1652     LOG_DIS("swap%s $r%u\n",
1653              swapmode_name(dc->op2, modename), dc->op1);
1654 
1655     cris_cc_mask(dc, CC_MASK_NZ);
1656     t0 = tcg_temp_new();
1657     tcg_gen_mov_tl(t0, cpu_R[dc->op1]);
1658     if (dc->op2 & 8) {
1659         tcg_gen_not_tl(t0, t0);
1660     }
1661     if (dc->op2 & 4) {
1662         t_gen_swapw(t0, t0);
1663     }
1664     if (dc->op2 & 2) {
1665         t_gen_swapb(t0, t0);
1666     }
1667     if (dc->op2 & 1) {
1668         t_gen_swapr(t0, t0);
1669     }
1670     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
1671     return 2;
1672 }
1673 
dec_or_r(CPUCRISState * env,DisasContext * dc)1674 static int dec_or_r(CPUCRISState *env, DisasContext *dc)
1675 {
1676     TCGv t[2];
1677     int size = memsize_zz(dc);
1678     LOG_DIS("or.%c $r%u, $r%u\n",
1679             memsize_char(size), dc->op1, dc->op2);
1680     cris_cc_mask(dc, CC_MASK_NZ);
1681     cris_alu_alloc_temps(dc, size, t);
1682     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1683     cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
1684     return 2;
1685 }
1686 
dec_addi_r(CPUCRISState * env,DisasContext * dc)1687 static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
1688 {
1689     TCGv t0;
1690     LOG_DIS("addi.%c $r%u, $r%u\n",
1691             memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1692     cris_cc_mask(dc, 0);
1693     t0 = tcg_temp_new();
1694     tcg_gen_shli_tl(t0, cpu_R[dc->op2], dc->zzsize);
1695     tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
1696     return 2;
1697 }
1698 
dec_addi_acr(CPUCRISState * env,DisasContext * dc)1699 static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
1700 {
1701     TCGv t0;
1702     LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
1703           memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
1704     cris_cc_mask(dc, 0);
1705     t0 = tcg_temp_new();
1706     tcg_gen_shli_tl(t0, cpu_R[dc->op2], dc->zzsize);
1707     tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
1708     return 2;
1709 }
1710 
dec_neg_r(CPUCRISState * env,DisasContext * dc)1711 static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
1712 {
1713     TCGv t[2];
1714     int size = memsize_zz(dc);
1715     LOG_DIS("neg.%c $r%u, $r%u\n",
1716             memsize_char(size), dc->op1, dc->op2);
1717     cris_cc_mask(dc, CC_MASK_NZVC);
1718     cris_alu_alloc_temps(dc, size, t);
1719     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1720 
1721     cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
1722     return 2;
1723 }
1724 
dec_btst_r(CPUCRISState * env,DisasContext * dc)1725 static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
1726 {
1727     LOG_DIS("btst $r%u, $r%u\n",
1728             dc->op1, dc->op2);
1729     cris_cc_mask(dc, CC_MASK_NZ);
1730     cris_evaluate_flags(dc);
1731         gen_helper_btst(cpu_PR[PR_CCS], tcg_env, cpu_R[dc->op2],
1732             cpu_R[dc->op1], cpu_PR[PR_CCS]);
1733     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
1734          cpu_R[dc->op2], cpu_R[dc->op2], 4);
1735     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1736     dc->flags_uptodate = 1;
1737     return 2;
1738 }
1739 
dec_sub_r(CPUCRISState * env,DisasContext * dc)1740 static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
1741 {
1742     TCGv t[2];
1743     int size = memsize_zz(dc);
1744     LOG_DIS("sub.%c $r%u, $r%u\n",
1745             memsize_char(size), dc->op1, dc->op2);
1746     cris_cc_mask(dc, CC_MASK_NZVC);
1747     cris_alu_alloc_temps(dc, size, t);
1748     dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
1749     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
1750     return 2;
1751 }
1752 
1753 /* Zero extension. From size to dword.  */
dec_movu_r(CPUCRISState * env,DisasContext * dc)1754 static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
1755 {
1756     TCGv t0;
1757     int size = memsize_z(dc);
1758     LOG_DIS("movu.%c $r%u, $r%u\n",
1759             memsize_char(size),
1760             dc->op1, dc->op2);
1761 
1762     cris_cc_mask(dc, CC_MASK_NZ);
1763     t0 = tcg_temp_new();
1764     dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
1765     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1766     return 2;
1767 }
1768 
1769 /* Sign extension. From size to dword.  */
dec_movs_r(CPUCRISState * env,DisasContext * dc)1770 static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
1771 {
1772     TCGv t0;
1773     int size = memsize_z(dc);
1774     LOG_DIS("movs.%c $r%u, $r%u\n",
1775             memsize_char(size),
1776             dc->op1, dc->op2);
1777 
1778     cris_cc_mask(dc, CC_MASK_NZ);
1779     t0 = tcg_temp_new();
1780     /* Size can only be qi or hi.  */
1781     t_gen_sext(t0, cpu_R[dc->op1], size);
1782     cris_alu(dc, CC_OP_MOVE,
1783             cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
1784     return 2;
1785 }
1786 
1787 /* zero extension. From size to dword.  */
dec_addu_r(CPUCRISState * env,DisasContext * dc)1788 static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
1789 {
1790     TCGv t0;
1791     int size = memsize_z(dc);
1792     LOG_DIS("addu.%c $r%u, $r%u\n",
1793             memsize_char(size),
1794             dc->op1, dc->op2);
1795 
1796     cris_cc_mask(dc, CC_MASK_NZVC);
1797     t0 = tcg_temp_new();
1798     /* Size can only be qi or hi.  */
1799     t_gen_zext(t0, cpu_R[dc->op1], size);
1800     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1801     return 2;
1802 }
1803 
1804 /* Sign extension. From size to dword.  */
dec_adds_r(CPUCRISState * env,DisasContext * dc)1805 static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
1806 {
1807     TCGv t0;
1808     int size = memsize_z(dc);
1809     LOG_DIS("adds.%c $r%u, $r%u\n",
1810             memsize_char(size),
1811             dc->op1, dc->op2);
1812 
1813     cris_cc_mask(dc, CC_MASK_NZVC);
1814     t0 = tcg_temp_new();
1815     /* Size can only be qi or hi.  */
1816     t_gen_sext(t0, cpu_R[dc->op1], size);
1817     cris_alu(dc, CC_OP_ADD,
1818             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1819     return 2;
1820 }
1821 
1822 /* Zero extension. From size to dword.  */
dec_subu_r(CPUCRISState * env,DisasContext * dc)1823 static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
1824 {
1825     TCGv t0;
1826     int size = memsize_z(dc);
1827     LOG_DIS("subu.%c $r%u, $r%u\n",
1828             memsize_char(size),
1829             dc->op1, dc->op2);
1830 
1831     cris_cc_mask(dc, CC_MASK_NZVC);
1832     t0 = tcg_temp_new();
1833     /* Size can only be qi or hi.  */
1834     t_gen_zext(t0, cpu_R[dc->op1], size);
1835     cris_alu(dc, CC_OP_SUB,
1836             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1837     return 2;
1838 }
1839 
1840 /* Sign extension. From size to dword.  */
dec_subs_r(CPUCRISState * env,DisasContext * dc)1841 static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
1842 {
1843     TCGv t0;
1844     int size = memsize_z(dc);
1845     LOG_DIS("subs.%c $r%u, $r%u\n",
1846             memsize_char(size),
1847             dc->op1, dc->op2);
1848 
1849     cris_cc_mask(dc, CC_MASK_NZVC);
1850     t0 = tcg_temp_new();
1851     /* Size can only be qi or hi.  */
1852     t_gen_sext(t0, cpu_R[dc->op1], size);
1853     cris_alu(dc, CC_OP_SUB,
1854             cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
1855     return 2;
1856 }
1857 
dec_setclrf(CPUCRISState * env,DisasContext * dc)1858 static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
1859 {
1860     uint32_t flags;
1861     int set = (~dc->opcode >> 2) & 1;
1862 
1863 
1864     flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1865         | EXTRACT_FIELD(dc->ir, 0, 3);
1866     if (set && flags == 0) {
1867         LOG_DIS("nop\n");
1868         return 2;
1869     } else if (!set && (flags & 0x20)) {
1870         LOG_DIS("di\n");
1871     } else {
1872         LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
1873     }
1874 
1875     /* User space is not allowed to touch these. Silently ignore.  */
1876     if (dc->tb_flags & U_FLAG) {
1877         flags &= ~(S_FLAG | I_FLAG | U_FLAG);
1878     }
1879 
1880     if (flags & X_FLAG) {
1881         if (set) {
1882             dc->flags_x = X_FLAG;
1883         } else {
1884             dc->flags_x = 0;
1885         }
1886     }
1887 
1888     /* Break the TB if any of the SPI flag changes.  */
1889     if (flags & (P_FLAG | S_FLAG)) {
1890         tcg_gen_movi_tl(env_pc, dc->pc + 2);
1891         dc->base.is_jmp = DISAS_UPDATE;
1892         dc->cpustate_changed = 1;
1893     }
1894 
1895     /* For the I flag, only act on posedge.  */
1896     if ((flags & I_FLAG)) {
1897         tcg_gen_movi_tl(env_pc, dc->pc + 2);
1898         dc->base.is_jmp = DISAS_UPDATE;
1899         dc->cpustate_changed = 1;
1900     }
1901 
1902 
1903     /* Simply decode the flags.  */
1904     cris_evaluate_flags(dc);
1905     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1906     cris_update_cc_x(dc);
1907     tcg_gen_movi_tl(cc_op, dc->cc_op);
1908 
1909     if (set) {
1910         if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
1911             /* Enter user mode.  */
1912             t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
1913             tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
1914             dc->cpustate_changed = 1;
1915         }
1916         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
1917     } else {
1918         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
1919     }
1920 
1921     dc->flags_uptodate = 1;
1922     dc->clear_x = 0;
1923     return 2;
1924 }
1925 
dec_move_rs(CPUCRISState * env,DisasContext * dc)1926 static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
1927 {
1928     TCGv c2, c1;
1929     LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
1930     c1 = tcg_constant_tl(dc->op1);
1931     c2 = tcg_constant_tl(dc->op2);
1932     cris_cc_mask(dc, 0);
1933     gen_helper_movl_sreg_reg(tcg_env, c2, c1);
1934     return 2;
1935 }
dec_move_sr(CPUCRISState * env,DisasContext * dc)1936 static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
1937 {
1938     TCGv c2, c1;
1939     LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
1940     c1 = tcg_constant_tl(dc->op1);
1941     c2 = tcg_constant_tl(dc->op2);
1942     cris_cc_mask(dc, 0);
1943     gen_helper_movl_reg_sreg(tcg_env, c1, c2);
1944     return 2;
1945 }
1946 
dec_move_rp(CPUCRISState * env,DisasContext * dc)1947 static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
1948 {
1949     TCGv t[2];
1950     LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
1951     cris_cc_mask(dc, 0);
1952 
1953     t[0] = tcg_temp_new();
1954     if (dc->op2 == PR_CCS) {
1955         cris_evaluate_flags(dc);
1956         tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
1957         if (dc->tb_flags & U_FLAG) {
1958             t[1] = tcg_temp_new();
1959             /* User space is not allowed to touch all flags.  */
1960             tcg_gen_andi_tl(t[0], t[0], 0x39f);
1961             tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
1962             tcg_gen_or_tl(t[0], t[1], t[0]);
1963         }
1964     } else {
1965         tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
1966     }
1967 
1968     t_gen_mov_preg_TN(dc, dc->op2, t[0]);
1969     if (dc->op2 == PR_CCS) {
1970         cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1971         dc->flags_uptodate = 1;
1972     }
1973     return 2;
1974 }
dec_move_pr(CPUCRISState * env,DisasContext * dc)1975 static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
1976 {
1977     TCGv t0;
1978     LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
1979     cris_cc_mask(dc, 0);
1980 
1981     if (dc->op2 == PR_CCS) {
1982         cris_evaluate_flags(dc);
1983     }
1984 
1985     if (dc->op2 == PR_DZ) {
1986         tcg_gen_movi_tl(cpu_R[dc->op1], 0);
1987     } else {
1988         t0 = tcg_temp_new();
1989         t_gen_mov_TN_preg(t0, dc->op2);
1990         cris_alu(dc, CC_OP_MOVE,
1991                 cpu_R[dc->op1], cpu_R[dc->op1], t0,
1992                 preg_sizes[dc->op2]);
1993     }
1994     return 2;
1995 }
1996 
dec_move_mr(CPUCRISState * env,DisasContext * dc)1997 static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
1998 {
1999     int memsize = memsize_zz(dc);
2000     int insn_len;
2001     LOG_DIS("move.%c [$r%u%s, $r%u\n",
2002             memsize_char(memsize),
2003             dc->op1, dc->postinc ? "+]" : "]",
2004                     dc->op2);
2005 
2006     if (memsize == 4) {
2007         insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
2008         cris_cc_mask(dc, CC_MASK_NZ);
2009         cris_update_cc_op(dc, CC_OP_MOVE, 4);
2010         cris_update_cc_x(dc);
2011         cris_update_result(dc, cpu_R[dc->op2]);
2012     } else {
2013         TCGv t0;
2014 
2015         t0 = tcg_temp_new();
2016         insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
2017         cris_cc_mask(dc, CC_MASK_NZ);
2018         cris_alu(dc, CC_OP_MOVE,
2019                 cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
2020     }
2021     do_postinc(dc, memsize);
2022     return insn_len;
2023 }
2024 
cris_alu_m_alloc_temps(TCGv * t)2025 static inline void cris_alu_m_alloc_temps(TCGv *t)
2026 {
2027     t[0] = tcg_temp_new();
2028     t[1] = tcg_temp_new();
2029 }
2030 
dec_movs_m(CPUCRISState * env,DisasContext * dc)2031 static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
2032 {
2033     TCGv t[2];
2034     int memsize = memsize_z(dc);
2035     int insn_len;
2036     LOG_DIS("movs.%c [$r%u%s, $r%u\n",
2037             memsize_char(memsize),
2038             dc->op1, dc->postinc ? "+]" : "]",
2039             dc->op2);
2040 
2041     cris_alu_m_alloc_temps(t);
2042     /* sign extend.  */
2043         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2044     cris_cc_mask(dc, CC_MASK_NZ);
2045     cris_alu(dc, CC_OP_MOVE,
2046             cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2047     do_postinc(dc, memsize);
2048     return insn_len;
2049 }
2050 
dec_addu_m(CPUCRISState * env,DisasContext * dc)2051 static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
2052 {
2053     TCGv t[2];
2054     int memsize = memsize_z(dc);
2055     int insn_len;
2056     LOG_DIS("addu.%c [$r%u%s, $r%u\n",
2057             memsize_char(memsize),
2058             dc->op1, dc->postinc ? "+]" : "]",
2059             dc->op2);
2060 
2061     cris_alu_m_alloc_temps(t);
2062     /* sign extend.  */
2063         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2064     cris_cc_mask(dc, CC_MASK_NZVC);
2065     cris_alu(dc, CC_OP_ADD,
2066             cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2067     do_postinc(dc, memsize);
2068     return insn_len;
2069 }
2070 
dec_adds_m(CPUCRISState * env,DisasContext * dc)2071 static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
2072 {
2073     TCGv t[2];
2074     int memsize = memsize_z(dc);
2075     int insn_len;
2076     LOG_DIS("adds.%c [$r%u%s, $r%u\n",
2077             memsize_char(memsize),
2078             dc->op1, dc->postinc ? "+]" : "]",
2079             dc->op2);
2080 
2081     cris_alu_m_alloc_temps(t);
2082     /* sign extend.  */
2083         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2084     cris_cc_mask(dc, CC_MASK_NZVC);
2085     cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2086     do_postinc(dc, memsize);
2087     return insn_len;
2088 }
2089 
dec_subu_m(CPUCRISState * env,DisasContext * dc)2090 static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
2091 {
2092     TCGv t[2];
2093     int memsize = memsize_z(dc);
2094     int insn_len;
2095     LOG_DIS("subu.%c [$r%u%s, $r%u\n",
2096             memsize_char(memsize),
2097             dc->op1, dc->postinc ? "+]" : "]",
2098             dc->op2);
2099 
2100     cris_alu_m_alloc_temps(t);
2101     /* sign extend.  */
2102         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2103     cris_cc_mask(dc, CC_MASK_NZVC);
2104     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2105     do_postinc(dc, memsize);
2106     return insn_len;
2107 }
2108 
dec_subs_m(CPUCRISState * env,DisasContext * dc)2109 static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
2110 {
2111     TCGv t[2];
2112     int memsize = memsize_z(dc);
2113     int insn_len;
2114     LOG_DIS("subs.%c [$r%u%s, $r%u\n",
2115             memsize_char(memsize),
2116             dc->op1, dc->postinc ? "+]" : "]",
2117             dc->op2);
2118 
2119     cris_alu_m_alloc_temps(t);
2120     /* sign extend.  */
2121         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2122     cris_cc_mask(dc, CC_MASK_NZVC);
2123     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2124     do_postinc(dc, memsize);
2125     return insn_len;
2126 }
2127 
dec_movu_m(CPUCRISState * env,DisasContext * dc)2128 static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
2129 {
2130     TCGv t[2];
2131     int memsize = memsize_z(dc);
2132     int insn_len;
2133 
2134     LOG_DIS("movu.%c [$r%u%s, $r%u\n",
2135             memsize_char(memsize),
2136             dc->op1, dc->postinc ? "+]" : "]",
2137             dc->op2);
2138 
2139     cris_alu_m_alloc_temps(t);
2140         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2141     cris_cc_mask(dc, CC_MASK_NZ);
2142     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2143     do_postinc(dc, memsize);
2144     return insn_len;
2145 }
2146 
dec_cmpu_m(CPUCRISState * env,DisasContext * dc)2147 static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
2148 {
2149     TCGv t[2];
2150     int memsize = memsize_z(dc);
2151     int insn_len;
2152     LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
2153             memsize_char(memsize),
2154             dc->op1, dc->postinc ? "+]" : "]",
2155             dc->op2);
2156 
2157     cris_alu_m_alloc_temps(t);
2158         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2159     cris_cc_mask(dc, CC_MASK_NZVC);
2160     cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
2161     do_postinc(dc, memsize);
2162     return insn_len;
2163 }
2164 
dec_cmps_m(CPUCRISState * env,DisasContext * dc)2165 static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
2166 {
2167     TCGv t[2];
2168     int memsize = memsize_z(dc);
2169     int insn_len;
2170     LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
2171             memsize_char(memsize),
2172             dc->op1, dc->postinc ? "+]" : "]",
2173             dc->op2);
2174 
2175     cris_alu_m_alloc_temps(t);
2176         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2177     cris_cc_mask(dc, CC_MASK_NZVC);
2178     cris_alu(dc, CC_OP_CMP,
2179             cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2180             memsize_zz(dc));
2181     do_postinc(dc, memsize);
2182     return insn_len;
2183 }
2184 
dec_cmp_m(CPUCRISState * env,DisasContext * dc)2185 static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
2186 {
2187     TCGv t[2];
2188     int memsize = memsize_zz(dc);
2189     int insn_len;
2190     LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
2191             memsize_char(memsize),
2192             dc->op1, dc->postinc ? "+]" : "]",
2193             dc->op2);
2194 
2195     cris_alu_m_alloc_temps(t);
2196         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2197     cris_cc_mask(dc, CC_MASK_NZVC);
2198     cris_alu(dc, CC_OP_CMP,
2199             cpu_R[dc->op2], cpu_R[dc->op2], t[1],
2200             memsize_zz(dc));
2201     do_postinc(dc, memsize);
2202     return insn_len;
2203 }
2204 
dec_test_m(CPUCRISState * env,DisasContext * dc)2205 static int dec_test_m(CPUCRISState *env, DisasContext *dc)
2206 {
2207     TCGv t[2], c;
2208     int memsize = memsize_zz(dc);
2209     int insn_len;
2210     LOG_DIS("test.%c [$r%u%s] op2=%x\n",
2211             memsize_char(memsize),
2212             dc->op1, dc->postinc ? "+]" : "]",
2213             dc->op2);
2214 
2215     cris_evaluate_flags(dc);
2216 
2217     cris_alu_m_alloc_temps(t);
2218         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2219     cris_cc_mask(dc, CC_MASK_NZ);
2220     tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
2221 
2222     c = tcg_constant_tl(0);
2223     cris_alu(dc, CC_OP_CMP,
2224          cpu_R[dc->op2], t[1], c, memsize_zz(dc));
2225     do_postinc(dc, memsize);
2226     return insn_len;
2227 }
2228 
dec_and_m(CPUCRISState * env,DisasContext * dc)2229 static int dec_and_m(CPUCRISState *env, DisasContext *dc)
2230 {
2231     TCGv t[2];
2232     int memsize = memsize_zz(dc);
2233     int insn_len;
2234     LOG_DIS("and.%c [$r%u%s, $r%u\n",
2235             memsize_char(memsize),
2236             dc->op1, dc->postinc ? "+]" : "]",
2237             dc->op2);
2238 
2239     cris_alu_m_alloc_temps(t);
2240         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2241     cris_cc_mask(dc, CC_MASK_NZ);
2242     cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2243     do_postinc(dc, memsize);
2244     return insn_len;
2245 }
2246 
dec_add_m(CPUCRISState * env,DisasContext * dc)2247 static int dec_add_m(CPUCRISState *env, DisasContext *dc)
2248 {
2249     TCGv t[2];
2250     int memsize = memsize_zz(dc);
2251     int insn_len;
2252     LOG_DIS("add.%c [$r%u%s, $r%u\n",
2253             memsize_char(memsize),
2254             dc->op1, dc->postinc ? "+]" : "]",
2255             dc->op2);
2256 
2257     cris_alu_m_alloc_temps(t);
2258         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2259     cris_cc_mask(dc, CC_MASK_NZVC);
2260     cris_alu(dc, CC_OP_ADD,
2261          cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2262     do_postinc(dc, memsize);
2263     return insn_len;
2264 }
2265 
dec_addo_m(CPUCRISState * env,DisasContext * dc)2266 static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
2267 {
2268     TCGv t[2];
2269     int memsize = memsize_zz(dc);
2270     int insn_len;
2271     LOG_DIS("add.%c [$r%u%s, $r%u\n",
2272             memsize_char(memsize),
2273             dc->op1, dc->postinc ? "+]" : "]",
2274             dc->op2);
2275 
2276     cris_alu_m_alloc_temps(t);
2277         insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
2278     cris_cc_mask(dc, 0);
2279     cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
2280     do_postinc(dc, memsize);
2281     return insn_len;
2282 }
2283 
dec_bound_m(CPUCRISState * env,DisasContext * dc)2284 static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
2285 {
2286     TCGv l[2];
2287     int memsize = memsize_zz(dc);
2288     int insn_len;
2289     LOG_DIS("bound.%c [$r%u%s, $r%u\n",
2290             memsize_char(memsize),
2291             dc->op1, dc->postinc ? "+]" : "]",
2292             dc->op2);
2293 
2294     l[0] = tcg_temp_new();
2295     l[1] = tcg_temp_new();
2296         insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
2297     cris_cc_mask(dc, CC_MASK_NZ);
2298     cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
2299     do_postinc(dc, memsize);
2300     return insn_len;
2301 }
2302 
dec_addc_mr(CPUCRISState * env,DisasContext * dc)2303 static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
2304 {
2305     TCGv t[2];
2306     int insn_len = 2;
2307     LOG_DIS("addc [$r%u%s, $r%u\n",
2308             dc->op1, dc->postinc ? "+]" : "]",
2309             dc->op2);
2310 
2311     cris_evaluate_flags(dc);
2312 
2313     /* Set for this insn.  */
2314     dc->flags_x = X_FLAG;
2315 
2316     cris_alu_m_alloc_temps(t);
2317         insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
2318     cris_cc_mask(dc, CC_MASK_NZVC);
2319     cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
2320     do_postinc(dc, 4);
2321     return insn_len;
2322 }
2323 
dec_sub_m(CPUCRISState * env,DisasContext * dc)2324 static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
2325 {
2326     TCGv t[2];
2327     int memsize = memsize_zz(dc);
2328     int insn_len;
2329     LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
2330             memsize_char(memsize),
2331             dc->op1, dc->postinc ? "+]" : "]",
2332             dc->op2, dc->ir, dc->zzsize);
2333 
2334     cris_alu_m_alloc_temps(t);
2335         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2336     cris_cc_mask(dc, CC_MASK_NZVC);
2337     cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
2338     do_postinc(dc, memsize);
2339     return insn_len;
2340 }
2341 
dec_or_m(CPUCRISState * env,DisasContext * dc)2342 static int dec_or_m(CPUCRISState *env, DisasContext *dc)
2343 {
2344     TCGv t[2];
2345     int memsize = memsize_zz(dc);
2346     int insn_len;
2347     LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
2348             memsize_char(memsize),
2349             dc->op1, dc->postinc ? "+]" : "]",
2350             dc->op2, dc->pc);
2351 
2352     cris_alu_m_alloc_temps(t);
2353         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2354     cris_cc_mask(dc, CC_MASK_NZ);
2355     cris_alu(dc, CC_OP_OR,
2356             cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
2357     do_postinc(dc, memsize);
2358     return insn_len;
2359 }
2360 
dec_move_mp(CPUCRISState * env,DisasContext * dc)2361 static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
2362 {
2363     TCGv t[2];
2364     int memsize = memsize_zz(dc);
2365     int insn_len = 2;
2366 
2367     LOG_DIS("move.%c [$r%u%s, $p%u\n",
2368             memsize_char(memsize),
2369             dc->op1,
2370             dc->postinc ? "+]" : "]",
2371             dc->op2);
2372 
2373     cris_alu_m_alloc_temps(t);
2374         insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
2375     cris_cc_mask(dc, 0);
2376     if (dc->op2 == PR_CCS) {
2377         cris_evaluate_flags(dc);
2378         if (dc->tb_flags & U_FLAG) {
2379             /* User space is not allowed to touch all flags.  */
2380             tcg_gen_andi_tl(t[1], t[1], 0x39f);
2381             tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
2382             tcg_gen_or_tl(t[1], t[0], t[1]);
2383         }
2384     }
2385 
2386     t_gen_mov_preg_TN(dc, dc->op2, t[1]);
2387 
2388     do_postinc(dc, memsize);
2389     return insn_len;
2390 }
2391 
dec_move_pm(CPUCRISState * env,DisasContext * dc)2392 static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
2393 {
2394     TCGv t0;
2395     int memsize;
2396 
2397     memsize = preg_sizes[dc->op2];
2398 
2399     LOG_DIS("move.%c $p%u, [$r%u%s\n",
2400             memsize_char(memsize),
2401             dc->op2, dc->op1, dc->postinc ? "+]" : "]");
2402 
2403     /* prepare store. Address in T0, value in T1.  */
2404     if (dc->op2 == PR_CCS) {
2405         cris_evaluate_flags(dc);
2406     }
2407     t0 = tcg_temp_new();
2408     t_gen_mov_TN_preg(t0, dc->op2);
2409     cris_flush_cc_state(dc);
2410     gen_store(dc, cpu_R[dc->op1], t0, memsize);
2411 
2412     cris_cc_mask(dc, 0);
2413     if (dc->postinc) {
2414         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2415     }
2416     return 2;
2417 }
2418 
dec_movem_mr(CPUCRISState * env,DisasContext * dc)2419 static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
2420 {
2421     TCGv_i64 tmp[16];
2422     TCGv tmp32;
2423     TCGv addr;
2424     int i;
2425     int nr = dc->op2 + 1;
2426 
2427     LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
2428             dc->postinc ? "+]" : "]", dc->op2);
2429 
2430     addr = tcg_temp_new();
2431     /* There are probably better ways of doing this.  */
2432     cris_flush_cc_state(dc);
2433     for (i = 0; i < (nr >> 1); i++) {
2434         tmp[i] = tcg_temp_new_i64();
2435         tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2436         gen_load64(dc, tmp[i], addr);
2437     }
2438     if (nr & 1) {
2439         tmp32 = tcg_temp_new_i32();
2440         tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
2441         gen_load(dc, tmp32, addr, 4, 0);
2442     } else {
2443         tmp32 = NULL;
2444     }
2445 
2446     for (i = 0; i < (nr >> 1); i++) {
2447         tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]);
2448         tcg_gen_shri_i64(tmp[i], tmp[i], 32);
2449         tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
2450     }
2451     if (nr & 1) {
2452         tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
2453     }
2454 
2455     /* writeback the updated pointer value.  */
2456     if (dc->postinc) {
2457         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
2458     }
2459 
2460     /* gen_load might want to evaluate the previous insns flags.  */
2461     cris_cc_mask(dc, 0);
2462     return 2;
2463 }
2464 
dec_movem_rm(CPUCRISState * env,DisasContext * dc)2465 static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
2466 {
2467     TCGv tmp;
2468     TCGv addr;
2469     int i;
2470 
2471     LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2472             dc->postinc ? "+]" : "]");
2473 
2474     cris_flush_cc_state(dc);
2475 
2476     tmp = tcg_temp_new();
2477     addr = tcg_temp_new();
2478     tcg_gen_movi_tl(tmp, 4);
2479     tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
2480     for (i = 0; i <= dc->op2; i++) {
2481         /* Displace addr.  */
2482         /* Perform the store.  */
2483         gen_store(dc, addr, cpu_R[i], 4);
2484         tcg_gen_add_tl(addr, addr, tmp);
2485     }
2486     if (dc->postinc) {
2487         tcg_gen_mov_tl(cpu_R[dc->op1], addr);
2488     }
2489     cris_cc_mask(dc, 0);
2490     return 2;
2491 }
2492 
dec_move_rm(CPUCRISState * env,DisasContext * dc)2493 static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
2494 {
2495     int memsize;
2496 
2497     memsize = memsize_zz(dc);
2498 
2499     LOG_DIS("move.%c $r%u, [$r%u]\n",
2500             memsize_char(memsize), dc->op2, dc->op1);
2501 
2502     /* prepare store.  */
2503     cris_flush_cc_state(dc);
2504     gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
2505 
2506     if (dc->postinc) {
2507         tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
2508     }
2509     cris_cc_mask(dc, 0);
2510     return 2;
2511 }
2512 
dec_lapcq(CPUCRISState * env,DisasContext * dc)2513 static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
2514 {
2515     LOG_DIS("lapcq %x, $r%u\n",
2516             dc->pc + dc->op1*2, dc->op2);
2517     cris_cc_mask(dc, 0);
2518     tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
2519     return 2;
2520 }
2521 
dec_lapc_im(CPUCRISState * env,DisasContext * dc)2522 static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
2523 {
2524     unsigned int rd;
2525     int32_t imm;
2526     int32_t pc;
2527 
2528     rd = dc->op2;
2529 
2530     cris_cc_mask(dc, 0);
2531     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2532     LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
2533 
2534     pc = dc->pc;
2535     pc += imm;
2536     tcg_gen_movi_tl(cpu_R[rd], pc);
2537     return 6;
2538 }
2539 
2540 /* Jump to special reg.  */
dec_jump_p(CPUCRISState * env,DisasContext * dc)2541 static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
2542 {
2543     LOG_DIS("jump $p%u\n", dc->op2);
2544 
2545     if (dc->op2 == PR_CCS) {
2546         cris_evaluate_flags(dc);
2547     }
2548     t_gen_mov_TN_preg(env_btarget, dc->op2);
2549     /* rete will often have low bit set to indicate delayslot.  */
2550     tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
2551     cris_cc_mask(dc, 0);
2552     cris_prepare_jmp(dc, JMP_INDIRECT);
2553     return 2;
2554 }
2555 
2556 /* Jump and save.  */
dec_jas_r(CPUCRISState * env,DisasContext * dc)2557 static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
2558 {
2559     TCGv c;
2560     LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
2561     cris_cc_mask(dc, 0);
2562     /* Store the return address in Pd.  */
2563     tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2564     if (dc->op2 > 15) {
2565         abort();
2566     }
2567     c = tcg_constant_tl(dc->pc + 4);
2568     t_gen_mov_preg_TN(dc, dc->op2, c);
2569 
2570     cris_prepare_jmp(dc, JMP_INDIRECT);
2571     return 2;
2572 }
2573 
dec_jas_im(CPUCRISState * env,DisasContext * dc)2574 static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
2575 {
2576     uint32_t imm;
2577     TCGv c;
2578 
2579     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2580 
2581     LOG_DIS("jas 0x%x\n", imm);
2582     cris_cc_mask(dc, 0);
2583     c = tcg_constant_tl(dc->pc + 8);
2584     /* Store the return address in Pd.  */
2585     t_gen_mov_preg_TN(dc, dc->op2, c);
2586 
2587     dc->jmp_pc = imm;
2588     cris_prepare_jmp(dc, JMP_DIRECT);
2589     return 6;
2590 }
2591 
dec_jasc_im(CPUCRISState * env,DisasContext * dc)2592 static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
2593 {
2594     uint32_t imm;
2595     TCGv c;
2596 
2597     imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2598 
2599     LOG_DIS("jasc 0x%x\n", imm);
2600     cris_cc_mask(dc, 0);
2601     c = tcg_constant_tl(dc->pc + 8 + 4);
2602     /* Store the return address in Pd.  */
2603     t_gen_mov_preg_TN(dc, dc->op2, c);
2604 
2605     dc->jmp_pc = imm;
2606     cris_prepare_jmp(dc, JMP_DIRECT);
2607     return 6;
2608 }
2609 
dec_jasc_r(CPUCRISState * env,DisasContext * dc)2610 static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
2611 {
2612     TCGv c;
2613     LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
2614     cris_cc_mask(dc, 0);
2615     /* Store the return address in Pd.  */
2616     tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
2617     c = tcg_constant_tl(dc->pc + 4 + 4);
2618     t_gen_mov_preg_TN(dc, dc->op2, c);
2619     cris_prepare_jmp(dc, JMP_INDIRECT);
2620     return 2;
2621 }
2622 
dec_bcc_im(CPUCRISState * env,DisasContext * dc)2623 static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
2624 {
2625     int32_t offset;
2626     uint32_t cond = dc->op2;
2627 
2628     offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
2629 
2630     LOG_DIS("b%s %d pc=%x dst=%x\n",
2631             cc_name(cond), offset,
2632             dc->pc, dc->pc + offset);
2633 
2634     cris_cc_mask(dc, 0);
2635     /* op2 holds the condition-code.  */
2636     cris_prepare_cc_branch(dc, offset, cond);
2637     return 4;
2638 }
2639 
dec_bas_im(CPUCRISState * env,DisasContext * dc)2640 static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
2641 {
2642     int32_t simm;
2643     TCGv c;
2644 
2645     simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2646 
2647     LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2648     cris_cc_mask(dc, 0);
2649     c = tcg_constant_tl(dc->pc + 8);
2650     /* Store the return address in Pd.  */
2651     t_gen_mov_preg_TN(dc, dc->op2, c);
2652 
2653     dc->jmp_pc = dc->pc + simm;
2654     cris_prepare_jmp(dc, JMP_DIRECT);
2655     return 6;
2656 }
2657 
dec_basc_im(CPUCRISState * env,DisasContext * dc)2658 static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
2659 {
2660     int32_t simm;
2661     TCGv c;
2662     simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
2663 
2664     LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
2665     cris_cc_mask(dc, 0);
2666     c = tcg_constant_tl(dc->pc + 12);
2667     /* Store the return address in Pd.  */
2668     t_gen_mov_preg_TN(dc, dc->op2, c);
2669 
2670     dc->jmp_pc = dc->pc + simm;
2671     cris_prepare_jmp(dc, JMP_DIRECT);
2672     return 6;
2673 }
2674 
dec_rfe_etc(CPUCRISState * env,DisasContext * dc)2675 static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
2676 {
2677     cris_cc_mask(dc, 0);
2678 
2679     if (dc->op2 == 15) {
2680         tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
2681                        -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
2682         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2683         t_gen_raise_exception(EXCP_HLT);
2684         dc->base.is_jmp = DISAS_NORETURN;
2685         return 2;
2686     }
2687 
2688     switch (dc->op2 & 7) {
2689     case 2:
2690         /* rfe.  */
2691         LOG_DIS("rfe\n");
2692         cris_evaluate_flags(dc);
2693         gen_helper_rfe(tcg_env);
2694         dc->base.is_jmp = DISAS_UPDATE;
2695         dc->cpustate_changed = true;
2696         break;
2697     case 5:
2698         /* rfn.  */
2699         LOG_DIS("rfn\n");
2700         cris_evaluate_flags(dc);
2701         gen_helper_rfn(tcg_env);
2702         dc->base.is_jmp = DISAS_UPDATE;
2703         dc->cpustate_changed = true;
2704         break;
2705     case 6:
2706         LOG_DIS("break %d\n", dc->op1);
2707         cris_evaluate_flags(dc);
2708         /* break.  */
2709         tcg_gen_movi_tl(env_pc, dc->pc + 2);
2710 
2711         /* Breaks start at 16 in the exception vector.  */
2712         t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
2713         t_gen_raise_exception(EXCP_BREAK);
2714         dc->base.is_jmp = DISAS_NORETURN;
2715         break;
2716     default:
2717         printf("op2=%x\n", dc->op2);
2718         BUG();
2719         break;
2720 
2721     }
2722     return 2;
2723 }
2724 
dec_ftag_fidx_d_m(CPUCRISState * env,DisasContext * dc)2725 static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
2726 {
2727     return 2;
2728 }
2729 
dec_ftag_fidx_i_m(CPUCRISState * env,DisasContext * dc)2730 static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
2731 {
2732     return 2;
2733 }
2734 
dec_null(CPUCRISState * env,DisasContext * dc)2735 static int dec_null(CPUCRISState *env, DisasContext *dc)
2736 {
2737     printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
2738         dc->pc, dc->opcode, dc->op1, dc->op2);
2739     fflush(NULL);
2740     BUG();
2741     return 2;
2742 }
2743 
2744 static const struct decoder_info {
2745     struct {
2746         uint32_t bits;
2747         uint32_t mask;
2748     };
2749     int (*dec)(CPUCRISState *env, DisasContext *dc);
2750 } decinfo[] = {
2751     /* Order matters here.  */
2752     {DEC_MOVEQ, dec_moveq},
2753     {DEC_BTSTQ, dec_btstq},
2754     {DEC_CMPQ, dec_cmpq},
2755     {DEC_ADDOQ, dec_addoq},
2756     {DEC_ADDQ, dec_addq},
2757     {DEC_SUBQ, dec_subq},
2758     {DEC_ANDQ, dec_andq},
2759     {DEC_ORQ, dec_orq},
2760     {DEC_ASRQ, dec_asrq},
2761     {DEC_LSLQ, dec_lslq},
2762     {DEC_LSRQ, dec_lsrq},
2763     {DEC_BCCQ, dec_bccq},
2764 
2765     {DEC_BCC_IM, dec_bcc_im},
2766     {DEC_JAS_IM, dec_jas_im},
2767     {DEC_JAS_R, dec_jas_r},
2768     {DEC_JASC_IM, dec_jasc_im},
2769     {DEC_JASC_R, dec_jasc_r},
2770     {DEC_BAS_IM, dec_bas_im},
2771     {DEC_BASC_IM, dec_basc_im},
2772     {DEC_JUMP_P, dec_jump_p},
2773     {DEC_LAPC_IM, dec_lapc_im},
2774     {DEC_LAPCQ, dec_lapcq},
2775 
2776     {DEC_RFE_ETC, dec_rfe_etc},
2777     {DEC_ADDC_MR, dec_addc_mr},
2778 
2779     {DEC_MOVE_MP, dec_move_mp},
2780     {DEC_MOVE_PM, dec_move_pm},
2781     {DEC_MOVEM_MR, dec_movem_mr},
2782     {DEC_MOVEM_RM, dec_movem_rm},
2783     {DEC_MOVE_PR, dec_move_pr},
2784     {DEC_SCC_R, dec_scc_r},
2785     {DEC_SETF, dec_setclrf},
2786     {DEC_CLEARF, dec_setclrf},
2787 
2788     {DEC_MOVE_SR, dec_move_sr},
2789     {DEC_MOVE_RP, dec_move_rp},
2790     {DEC_SWAP_R, dec_swap_r},
2791     {DEC_ABS_R, dec_abs_r},
2792     {DEC_LZ_R, dec_lz_r},
2793     {DEC_MOVE_RS, dec_move_rs},
2794     {DEC_BTST_R, dec_btst_r},
2795     {DEC_ADDC_R, dec_addc_r},
2796 
2797     {DEC_DSTEP_R, dec_dstep_r},
2798     {DEC_XOR_R, dec_xor_r},
2799     {DEC_MCP_R, dec_mcp_r},
2800     {DEC_CMP_R, dec_cmp_r},
2801 
2802     {DEC_ADDI_R, dec_addi_r},
2803     {DEC_ADDI_ACR, dec_addi_acr},
2804 
2805     {DEC_ADD_R, dec_add_r},
2806     {DEC_SUB_R, dec_sub_r},
2807 
2808     {DEC_ADDU_R, dec_addu_r},
2809     {DEC_ADDS_R, dec_adds_r},
2810     {DEC_SUBU_R, dec_subu_r},
2811     {DEC_SUBS_R, dec_subs_r},
2812     {DEC_LSL_R, dec_lsl_r},
2813 
2814     {DEC_AND_R, dec_and_r},
2815     {DEC_OR_R, dec_or_r},
2816     {DEC_BOUND_R, dec_bound_r},
2817     {DEC_ASR_R, dec_asr_r},
2818     {DEC_LSR_R, dec_lsr_r},
2819 
2820     {DEC_MOVU_R, dec_movu_r},
2821     {DEC_MOVS_R, dec_movs_r},
2822     {DEC_NEG_R, dec_neg_r},
2823     {DEC_MOVE_R, dec_move_r},
2824 
2825     {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
2826     {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
2827 
2828     {DEC_MULS_R, dec_muls_r},
2829     {DEC_MULU_R, dec_mulu_r},
2830 
2831     {DEC_ADDU_M, dec_addu_m},
2832     {DEC_ADDS_M, dec_adds_m},
2833     {DEC_SUBU_M, dec_subu_m},
2834     {DEC_SUBS_M, dec_subs_m},
2835 
2836     {DEC_CMPU_M, dec_cmpu_m},
2837     {DEC_CMPS_M, dec_cmps_m},
2838     {DEC_MOVU_M, dec_movu_m},
2839     {DEC_MOVS_M, dec_movs_m},
2840 
2841     {DEC_CMP_M, dec_cmp_m},
2842     {DEC_ADDO_M, dec_addo_m},
2843     {DEC_BOUND_M, dec_bound_m},
2844     {DEC_ADD_M, dec_add_m},
2845     {DEC_SUB_M, dec_sub_m},
2846     {DEC_AND_M, dec_and_m},
2847     {DEC_OR_M, dec_or_m},
2848     {DEC_MOVE_RM, dec_move_rm},
2849     {DEC_TEST_M, dec_test_m},
2850     {DEC_MOVE_MR, dec_move_mr},
2851 
2852     {{0, 0}, dec_null}
2853 };
2854 
crisv32_decoder(CPUCRISState * env,DisasContext * dc)2855 static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
2856 {
2857     int insn_len = 2;
2858     int i;
2859 
2860     /* Load a halfword onto the instruction register.  */
2861     dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
2862 
2863     /* Now decode it.  */
2864     dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
2865     dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
2866     dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
2867     dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
2868     dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
2869     dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
2870 
2871     /* Large switch for all insns.  */
2872     for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
2873         if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
2874             insn_len = decinfo[i].dec(env, dc);
2875             break;
2876         }
2877     }
2878 
2879 #if !defined(CONFIG_USER_ONLY)
2880     /* Single-stepping ?  */
2881     if (dc->tb_flags & S_FLAG) {
2882         TCGLabel *l1 = gen_new_label();
2883         tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
2884         /* We treat SPC as a break with an odd trap vector.  */
2885         cris_evaluate_flags(dc);
2886         t_gen_movi_env_TN(trap_vector, 3);
2887         tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
2888         tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
2889         t_gen_raise_exception(EXCP_BREAK);
2890         gen_set_label(l1);
2891     }
2892 #endif
2893     return insn_len;
2894 }
2895 
2896 #include "translate_v10.c.inc"
2897 
2898 /*
2899  * Delay slots on QEMU/CRIS.
2900  *
2901  * If an exception hits on a delayslot, the core will let ERP (the Exception
2902  * Return Pointer) point to the branch (the previous) insn and set the lsb to
2903  * to give SW a hint that the exception actually hit on the dslot.
2904  *
2905  * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
2906  * the core and any jmp to an odd addresses will mask off that lsb. It is
2907  * simply there to let sw know there was an exception on a dslot.
2908  *
2909  * When the software returns from an exception, the branch will re-execute.
2910  * On QEMU care needs to be taken when a branch+delayslot sequence is broken
2911  * and the branch and delayslot don't share pages.
2912  *
2913  * The TB containing the branch insn will set up env->btarget and evaluate
2914  * env->btaken. When the translation loop exits we will note that the branch
2915  * sequence is broken and let env->dslot be the size of the branch insn (those
2916  * vary in length).
2917  *
2918  * The TB containing the delayslot will have the PC of its real insn (i.e no lsb
2919  * set). It will also expect to have env->dslot setup with the size of the
2920  * delay slot so that env->pc - env->dslot point to the branch insn. This TB
2921  * will execute the dslot and take the branch, either to btarget or just one
2922  * insn ahead.
2923  *
2924  * When exceptions occur, we check for env->dslot in do_interrupt to detect
2925  * broken branch sequences and setup $erp accordingly (i.e let it point to the
2926  * branch and set lsb). Then env->dslot gets cleared so that the exception
2927  * handler can enter. When returning from exceptions (jump $erp) the lsb gets
2928  * masked off and we will reexecute the branch insn.
2929  *
2930  */
2931 
cris_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)2932 static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2933 {
2934     DisasContext *dc = container_of(dcbase, DisasContext, base);
2935     CPUCRISState *env = cpu_env(cs);
2936     uint32_t tb_flags = dc->base.tb->flags;
2937     uint32_t pc_start;
2938 
2939     if (env->pregs[PR_VR] == 32) {
2940         dc->decoder = crisv32_decoder;
2941         dc->clear_locked_irq = 0;
2942     } else {
2943         dc->decoder = crisv10_decoder;
2944         dc->clear_locked_irq = 1;
2945     }
2946 
2947     /*
2948      * Odd PC indicates that branch is rexecuting due to exception in the
2949      * delayslot, like in real hw.
2950      */
2951     pc_start = dc->base.pc_first & ~1;
2952     dc->base.pc_first = pc_start;
2953     dc->base.pc_next = pc_start;
2954 
2955     dc->cpu = env_archcpu(env);
2956     dc->ppc = pc_start;
2957     dc->pc = pc_start;
2958     dc->mem_index = cpu_mmu_index(cs, false);
2959     dc->flags_uptodate = 1;
2960     dc->flags_x = tb_flags & X_FLAG;
2961     dc->cc_x_uptodate = 0;
2962     dc->cc_mask = 0;
2963     dc->update_cc = 0;
2964     dc->clear_prefix = 0;
2965     dc->cpustate_changed = 0;
2966 
2967     cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2968     dc->cc_size_uptodate = -1;
2969 
2970     /* Decode TB flags.  */
2971     dc->tb_flags = tb_flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG | PFIX_FLAG);
2972     dc->delayed_branch = !!(tb_flags & 7);
2973     if (dc->delayed_branch) {
2974         dc->jmp = JMP_INDIRECT;
2975     } else {
2976         dc->jmp = JMP_NOJMP;
2977     }
2978 }
2979 
cris_tr_tb_start(DisasContextBase * db,CPUState * cpu)2980 static void cris_tr_tb_start(DisasContextBase *db, CPUState *cpu)
2981 {
2982 }
2983 
cris_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)2984 static void cris_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
2985 {
2986     DisasContext *dc = container_of(dcbase, DisasContext, base);
2987 
2988     tcg_gen_insn_start(dc->delayed_branch == 1 ? dc->ppc | 1 : dc->pc);
2989 }
2990 
cris_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)2991 static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2992 {
2993     DisasContext *dc = container_of(dcbase, DisasContext, base);
2994     unsigned int insn_len;
2995 
2996     /* Pretty disas.  */
2997     LOG_DIS("%8.8x:\t", dc->pc);
2998 
2999     dc->clear_x = 1;
3000 
3001     insn_len = dc->decoder(cpu_env(cs), dc);
3002     dc->ppc = dc->pc;
3003     dc->pc += insn_len;
3004     dc->base.pc_next += insn_len;
3005 
3006     if (dc->base.is_jmp == DISAS_NORETURN) {
3007         return;
3008     }
3009 
3010     if (dc->clear_x) {
3011         cris_clear_x_flag(dc);
3012     }
3013 
3014     /*
3015      * All branches are delayed branches, handled immediately below.
3016      * We don't expect to see odd combinations of exit conditions.
3017      */
3018     assert(dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed);
3019 
3020     if (dc->delayed_branch && --dc->delayed_branch == 0) {
3021         dc->base.is_jmp = DISAS_DBRANCH;
3022         return;
3023     }
3024 
3025     if (dc->base.is_jmp != DISAS_NEXT) {
3026         return;
3027     }
3028 
3029     /* Force an update if the per-tb cpu state has changed.  */
3030     if (dc->cpustate_changed) {
3031         dc->base.is_jmp = DISAS_UPDATE_NEXT;
3032         return;
3033     }
3034 
3035     /*
3036      * FIXME: Only the first insn in the TB should cross a page boundary.
3037      * If we can detect the length of the next insn easily, we should.
3038      * In the meantime, simply stop when we do cross.
3039      */
3040     if ((dc->pc ^ dc->base.pc_first) & TARGET_PAGE_MASK) {
3041         dc->base.is_jmp = DISAS_TOO_MANY;
3042     }
3043 }
3044 
cris_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)3045 static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
3046 {
3047     DisasContext *dc = container_of(dcbase, DisasContext, base);
3048     DisasJumpType is_jmp = dc->base.is_jmp;
3049     target_ulong npc = dc->pc;
3050 
3051     if (is_jmp == DISAS_NORETURN) {
3052         /* If we have a broken branch+delayslot sequence, it's too late. */
3053         assert(dc->delayed_branch != 1);
3054         return;
3055     }
3056 
3057     if (dc->clear_locked_irq) {
3058         t_gen_movi_env_TN(locked_irq, 0);
3059     }
3060 
3061     /* Broken branch+delayslot sequence.  */
3062     if (dc->delayed_branch == 1) {
3063         /* Set env->dslot to the size of the branch insn.  */
3064         t_gen_movi_env_TN(dslot, dc->pc - dc->ppc);
3065         cris_store_direct_jmp(dc);
3066     }
3067 
3068     cris_evaluate_flags(dc);
3069 
3070     /* Evaluate delayed branch destination and fold to another is_jmp case. */
3071     if (is_jmp == DISAS_DBRANCH) {
3072         if (dc->base.tb->flags & 7) {
3073             t_gen_movi_env_TN(dslot, 0);
3074         }
3075 
3076         switch (dc->jmp) {
3077         case JMP_DIRECT:
3078             npc = dc->jmp_pc;
3079             is_jmp = dc->cpustate_changed ? DISAS_UPDATE_NEXT : DISAS_TOO_MANY;
3080             break;
3081 
3082         case JMP_DIRECT_CC:
3083             /*
3084              * Use a conditional branch if either taken or not-taken path
3085              * can use goto_tb.  If neither can, then treat it as indirect.
3086              */
3087             if (likely(!dc->cpustate_changed)
3088                 && (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
3089                 TCGLabel *not_taken = gen_new_label();
3090 
3091                 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
3092                 gen_goto_tb(dc, 1, dc->jmp_pc);
3093                 gen_set_label(not_taken);
3094 
3095                 /* not-taken case handled below. */
3096                 is_jmp = DISAS_TOO_MANY;
3097                 break;
3098             }
3099             tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
3100             /* fall through */
3101 
3102         case JMP_INDIRECT:
3103             tcg_gen_movcond_tl(TCG_COND_NE, env_pc,
3104                                env_btaken, tcg_constant_tl(0),
3105                                env_btarget, tcg_constant_tl(npc));
3106             is_jmp = dc->cpustate_changed ? DISAS_UPDATE : DISAS_JUMP;
3107 
3108             /*
3109              * We have now consumed btaken and btarget.  Hint to the
3110              * tcg compiler that the writeback to env may be dropped.
3111              */
3112             tcg_gen_discard_tl(env_btaken);
3113             tcg_gen_discard_tl(env_btarget);
3114             break;
3115 
3116         default:
3117             g_assert_not_reached();
3118         }
3119     }
3120 
3121     switch (is_jmp) {
3122     case DISAS_TOO_MANY:
3123         gen_goto_tb(dc, 0, npc);
3124         break;
3125     case DISAS_UPDATE_NEXT:
3126         tcg_gen_movi_tl(env_pc, npc);
3127         /* fall through */
3128     case DISAS_JUMP:
3129         tcg_gen_lookup_and_goto_ptr();
3130         break;
3131     case DISAS_UPDATE:
3132         /* Indicate that interrupts must be re-evaluated before the next TB. */
3133         tcg_gen_exit_tb(NULL, 0);
3134         break;
3135     default:
3136         g_assert_not_reached();
3137     }
3138 }
3139 
3140 static const TranslatorOps cris_tr_ops = {
3141     .init_disas_context = cris_tr_init_disas_context,
3142     .tb_start           = cris_tr_tb_start,
3143     .insn_start         = cris_tr_insn_start,
3144     .translate_insn     = cris_tr_translate_insn,
3145     .tb_stop            = cris_tr_tb_stop,
3146 };
3147 
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)3148 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
3149                            vaddr pc, void *host_pc)
3150 {
3151     DisasContext dc;
3152     translator_loop(cs, tb, max_insns, pc, host_pc, &cris_tr_ops, &dc.base);
3153 }
3154 
cris_cpu_dump_state(CPUState * cs,FILE * f,int flags)3155 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
3156 {
3157     CPUCRISState *env = cpu_env(cs);
3158     const char * const *regnames;
3159     const char * const *pregnames;
3160     int i;
3161 
3162     if (!env) {
3163         return;
3164     }
3165     if (env->pregs[PR_VR] < 32) {
3166         pregnames = pregnames_v10;
3167         regnames = regnames_v10;
3168     } else {
3169         pregnames = pregnames_v32;
3170         regnames = regnames_v32;
3171     }
3172 
3173     qemu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3174                  "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3175                  env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3176                  env->cc_op,
3177                  env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3178 
3179 
3180     for (i = 0; i < 16; i++) {
3181         qemu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3182         if ((i + 1) % 4 == 0) {
3183             qemu_fprintf(f, "\n");
3184         }
3185     }
3186     qemu_fprintf(f, "\nspecial regs:\n");
3187     for (i = 0; i < 16; i++) {
3188         qemu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3189         if ((i + 1) % 4 == 0) {
3190             qemu_fprintf(f, "\n");
3191         }
3192     }
3193     if (env->pregs[PR_VR] >= 32) {
3194         uint32_t srs = env->pregs[PR_SRS];
3195         qemu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3196         if (srs < ARRAY_SIZE(env->sregs)) {
3197             for (i = 0; i < 16; i++) {
3198                 qemu_fprintf(f, "s%2.2d=%8.8x ",
3199                              i, env->sregs[srs][i]);
3200                 if ((i + 1) % 4 == 0) {
3201                     qemu_fprintf(f, "\n");
3202                 }
3203             }
3204         }
3205     }
3206     qemu_fprintf(f, "\n\n");
3207 
3208 }
3209 
cris_initialize_tcg(void)3210 void cris_initialize_tcg(void)
3211 {
3212     int i;
3213 
3214     cc_x = tcg_global_mem_new(tcg_env,
3215                               offsetof(CPUCRISState, cc_x), "cc_x");
3216     cc_src = tcg_global_mem_new(tcg_env,
3217                                 offsetof(CPUCRISState, cc_src), "cc_src");
3218     cc_dest = tcg_global_mem_new(tcg_env,
3219                                  offsetof(CPUCRISState, cc_dest),
3220                                  "cc_dest");
3221     cc_result = tcg_global_mem_new(tcg_env,
3222                                    offsetof(CPUCRISState, cc_result),
3223                                    "cc_result");
3224     cc_op = tcg_global_mem_new(tcg_env,
3225                                offsetof(CPUCRISState, cc_op), "cc_op");
3226     cc_size = tcg_global_mem_new(tcg_env,
3227                                  offsetof(CPUCRISState, cc_size),
3228                                  "cc_size");
3229     cc_mask = tcg_global_mem_new(tcg_env,
3230                                  offsetof(CPUCRISState, cc_mask),
3231                                  "cc_mask");
3232 
3233     env_pc = tcg_global_mem_new(tcg_env,
3234                                 offsetof(CPUCRISState, pc),
3235                                 "pc");
3236     env_btarget = tcg_global_mem_new(tcg_env,
3237                                      offsetof(CPUCRISState, btarget),
3238                                      "btarget");
3239     env_btaken = tcg_global_mem_new(tcg_env,
3240                                     offsetof(CPUCRISState, btaken),
3241                                     "btaken");
3242     for (i = 0; i < 16; i++) {
3243         cpu_R[i] = tcg_global_mem_new(tcg_env,
3244                                       offsetof(CPUCRISState, regs[i]),
3245                                       regnames_v32[i]);
3246     }
3247     for (i = 0; i < 16; i++) {
3248         cpu_PR[i] = tcg_global_mem_new(tcg_env,
3249                                        offsetof(CPUCRISState, pregs[i]),
3250                                        pregnames_v32[i]);
3251     }
3252 }
3253