|
|
1.1 root 1: /*
2: * CRISv10 emulation for qemu: main translation routines.
3: *
4: * Copyright (c) 2010 AXIS Communications AB
5: * Written by Edgar E. Iglesias.
6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19: */
20:
21: #include "crisv10-decode.h"
22:
23: static const char *regnames_v10[] =
24: {
25: "$r0", "$r1", "$r2", "$r3",
26: "$r4", "$r5", "$r6", "$r7",
27: "$r8", "$r9", "$r10", "$r11",
28: "$r12", "$r13", "$sp", "$pc",
29: };
30:
31: static const char *pregnames_v10[] =
32: {
33: "$bz", "$vr", "$p2", "$p3",
34: "$wz", "$ccr", "$p6-prefix", "$mof",
35: "$dz", "$ibr", "$irp", "$srp",
36: "$bar", "$dccr", "$brp", "$usp",
37: };
38:
39: /* We need this table to handle preg-moves with implicit width. */
40: static int preg_sizes_v10[] = {
41: 1, /* bz. */
42: 1, /* vr. */
43: 1, /* pid. */
44: 1, /* srs. */
45: 2, /* wz. */
46: 2, 2, 4,
47: 4, 4, 4, 4,
48: 4, 4, 4, 4,
49: };
50:
51: static inline int dec10_size(unsigned int size)
52: {
53: size++;
54: if (size == 3)
55: size++;
56: return size;
57: }
58:
59: static inline void cris_illegal_insn(DisasContext *dc)
60: {
61: qemu_log("illegal insn at pc=%x\n", dc->pc);
62: t_gen_raise_exception(EXCP_BREAK);
63: }
64:
1.1.1.4 root 65: static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
66: unsigned int size, int mem_index)
67: {
68: int l1 = gen_new_label();
69: TCGv taddr = tcg_temp_local_new();
70: TCGv tval = tcg_temp_local_new();
71: TCGv t1 = tcg_temp_local_new();
72: dc->postinc = 0;
73: cris_evaluate_flags(dc);
74:
75: tcg_gen_mov_tl(taddr, addr);
76: tcg_gen_mov_tl(tval, val);
77:
78: /* Store only if F flag isn't set */
79: tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
80: tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
81: if (size == 1) {
82: tcg_gen_qemu_st8(tval, taddr, mem_index);
83: } else if (size == 2) {
84: tcg_gen_qemu_st16(tval, taddr, mem_index);
85: } else {
86: tcg_gen_qemu_st32(tval, taddr, mem_index);
87: }
88: gen_set_label(l1);
89: tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */
90: tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
91: tcg_temp_free(t1);
92: tcg_temp_free(tval);
93: tcg_temp_free(taddr);
94: }
95:
96: static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
97: unsigned int size)
98: {
99: int mem_index = cpu_mmu_index(dc->env);
100:
101: /* If we get a fault on a delayslot we must keep the jmp state in
102: the cpu-state to be able to re-execute the jmp. */
103: if (dc->delayed_branch == 1) {
104: cris_store_direct_jmp(dc);
105: }
106:
107: /* Conditional writes. We only support the kind were X is known
108: at translation time. */
109: if (dc->flagx_known && dc->flags_x) {
110: gen_store_v10_conditional(dc, addr, val, size, mem_index);
111: return;
112: }
113:
114: if (size == 1) {
115: tcg_gen_qemu_st8(val, addr, mem_index);
116: } else if (size == 2) {
117: tcg_gen_qemu_st16(val, addr, mem_index);
118: } else {
119: tcg_gen_qemu_st32(val, addr, mem_index);
120: }
121: }
122:
123:
1.1 root 124: /* Prefix flag and register are used to handle the more complex
125: addressing modes. */
126: static void cris_set_prefix(DisasContext *dc)
127: {
128: dc->clear_prefix = 0;
129: dc->tb_flags |= PFIX_FLAG;
130: tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG);
131:
132: /* prefix insns dont clear the x flag. */
133: dc->clear_x = 0;
134: cris_lock_irq(dc);
135: }
136:
137: static void crisv10_prepare_memaddr(DisasContext *dc,
138: TCGv addr, unsigned int size)
139: {
140: if (dc->tb_flags & PFIX_FLAG) {
141: tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]);
142: } else {
143: tcg_gen_mov_tl(addr, cpu_R[dc->src]);
144: }
145: }
146:
147: static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
148: {
149: unsigned int insn_len = 0;
150:
151: if (dc->tb_flags & PFIX_FLAG) {
152: if (dc->mode == CRISV10_MODE_AUTOINC) {
153: tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]);
154: }
155: } else {
156: if (dc->mode == CRISV10_MODE_AUTOINC) {
157: if (dc->src == 15) {
158: insn_len += size & ~1;
159: } else {
160: tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size);
161: }
162: }
163: }
164: return insn_len;
165: }
166:
167: static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
168: TCGv dst)
169: {
1.1.1.2 root 170: unsigned int rs;
1.1 root 171: uint32_t imm;
172: int is_imm;
173: int insn_len = 0;
174:
175: rs = dc->src;
176: is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG);
177: LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n",
1.1.1.2 root 178: rs, dc->dst, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG);
1.1 root 179:
180: /* Load [$rs] onto T1. */
181: if (is_imm) {
182: if (memsize != 4) {
183: if (s_ext) {
184: if (memsize == 1)
185: imm = ldsb_code(dc->pc + 2);
186: else
187: imm = ldsw_code(dc->pc + 2);
188: } else {
189: if (memsize == 1)
190: imm = ldub_code(dc->pc + 2);
191: else
192: imm = lduw_code(dc->pc + 2);
193: }
194: } else
195: imm = ldl_code(dc->pc + 2);
196:
197: tcg_gen_movi_tl(dst, imm);
198:
199: if (dc->mode == CRISV10_MODE_AUTOINC) {
200: insn_len += memsize;
201: if (memsize == 1)
202: insn_len++;
203: tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len);
204: }
205: } else {
206: TCGv addr;
207:
208: addr = tcg_temp_new();
209: cris_flush_cc_state(dc);
210: crisv10_prepare_memaddr(dc, addr, memsize);
211: gen_load(dc, dst, addr, memsize, 0);
212: if (s_ext)
213: t_gen_sext(dst, dst, memsize);
214: else
215: t_gen_zext(dst, dst, memsize);
216: insn_len += crisv10_post_memaddr(dc, memsize);
217: tcg_temp_free(addr);
218: }
219:
220: if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) {
221: dc->dst = dc->src;
222: }
223: return insn_len;
224: }
225:
226: static unsigned int dec10_quick_imm(DisasContext *dc)
227: {
228: int32_t imm, simm;
229: int op;
230:
231: /* sign extend. */
232: imm = dc->ir & ((1 << 6) - 1);
233: simm = (int8_t) (imm << 2);
234: simm >>= 2;
235: switch (dc->opcode) {
236: case CRISV10_QIMM_BDAP_R0:
237: case CRISV10_QIMM_BDAP_R1:
238: case CRISV10_QIMM_BDAP_R2:
239: case CRISV10_QIMM_BDAP_R3:
240: simm = (int8_t)dc->ir;
241: LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
242: LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
243: dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
244: cris_set_prefix(dc);
245: if (dc->dst == 15) {
246: tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
247: } else {
248: tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
249: }
250: break;
251:
252: case CRISV10_QIMM_MOVEQ:
253: LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);
254:
255: cris_cc_mask(dc, CC_MASK_NZVC);
256: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
257: cpu_R[dc->dst], tcg_const_tl(simm), 4);
258: break;
259: case CRISV10_QIMM_CMPQ:
260: LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);
261:
262: cris_cc_mask(dc, CC_MASK_NZVC);
263: cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
264: cpu_R[dc->dst], tcg_const_tl(simm), 4);
265: break;
266: case CRISV10_QIMM_ADDQ:
267: LOG_DIS("addq %d, $r%d\n", imm, dc->dst);
268:
269: cris_cc_mask(dc, CC_MASK_NZVC);
270: cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
271: cpu_R[dc->dst], tcg_const_tl(imm), 4);
272: break;
273: case CRISV10_QIMM_ANDQ:
274: LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
275:
276: cris_cc_mask(dc, CC_MASK_NZVC);
277: cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
278: cpu_R[dc->dst], tcg_const_tl(simm), 4);
279: break;
280: case CRISV10_QIMM_ASHQ:
281: LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);
282:
283: cris_cc_mask(dc, CC_MASK_NZVC);
284: op = imm & (1 << 5);
285: imm &= 0x1f;
286: if (op) {
287: cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
288: cpu_R[dc->dst], tcg_const_tl(imm), 4);
289: } else {
290: /* BTST */
291: cris_update_cc_op(dc, CC_OP_FLAGS, 4);
292: gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
293: tcg_const_tl(imm), cpu_PR[PR_CCS]);
294: }
295: break;
296: case CRISV10_QIMM_LSHQ:
297: LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);
298:
299: op = CC_OP_LSL;
300: if (imm & (1 << 5)) {
301: op = CC_OP_LSR;
302: }
303: imm &= 0x1f;
304: cris_cc_mask(dc, CC_MASK_NZVC);
305: cris_alu(dc, op, cpu_R[dc->dst],
306: cpu_R[dc->dst], tcg_const_tl(imm), 4);
307: break;
308: case CRISV10_QIMM_SUBQ:
309: LOG_DIS("subq %d, $r%d\n", imm, dc->dst);
310:
311: cris_cc_mask(dc, CC_MASK_NZVC);
312: cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
313: cpu_R[dc->dst], tcg_const_tl(imm), 4);
314: break;
315: case CRISV10_QIMM_ORQ:
316: LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
317:
318: cris_cc_mask(dc, CC_MASK_NZVC);
319: cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
320: cpu_R[dc->dst], tcg_const_tl(simm), 4);
321: break;
322:
323: case CRISV10_QIMM_BCC_R0:
324: case CRISV10_QIMM_BCC_R1:
325: case CRISV10_QIMM_BCC_R2:
326: case CRISV10_QIMM_BCC_R3:
327: imm = dc->ir & 0xff;
328: /* bit 0 is a sign bit. */
329: if (imm & 1) {
330: imm |= 0xffffff00; /* sign extend. */
331: imm &= ~1; /* get rid of the sign bit. */
332: }
333: imm += 2;
334: LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);
335:
336: cris_cc_mask(dc, 0);
337: cris_prepare_cc_branch(dc, imm, dc->cond);
338: break;
339:
340: default:
341: LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
342: dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
343: cpu_abort(dc->env, "Unhandled quickimm\n");
344: break;
345: }
346: return 2;
347: }
348:
349: static unsigned int dec10_setclrf(DisasContext *dc)
350: {
351: uint32_t flags;
352: unsigned int set = ~dc->opcode & 1;
353:
354: flags = EXTRACT_FIELD(dc->ir, 0, 3)
355: | (EXTRACT_FIELD(dc->ir, 12, 15) << 4);
356: LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags);
357:
358:
359: if (flags & X_FLAG) {
360: dc->flagx_known = 1;
361: if (set)
362: dc->flags_x = X_FLAG;
363: else
364: dc->flags_x = 0;
365: }
366:
367: cris_evaluate_flags (dc);
368: cris_update_cc_op(dc, CC_OP_FLAGS, 4);
369: cris_update_cc_x(dc);
370: tcg_gen_movi_tl(cc_op, dc->cc_op);
371:
372: if (set) {
373: tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
374: } else {
1.1.1.4 root 375: tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
376: ~(flags|F_FLAG_V10|P_FLAG_V10));
1.1 root 377: }
378:
379: dc->flags_uptodate = 1;
380: dc->clear_x = 0;
381: cris_lock_irq(dc);
382: return 2;
383: }
384:
385: static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext,
386: TCGv dd, TCGv ds, TCGv sd, TCGv ss)
387: {
388: if (sext) {
389: t_gen_sext(dd, sd, size);
390: t_gen_sext(ds, ss, size);
391: } else {
392: t_gen_zext(dd, sd, size);
393: t_gen_zext(ds, ss, size);
394: }
395: }
396:
397: static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext)
398: {
399: TCGv t[2];
400:
401: t[0] = tcg_temp_new();
402: t[1] = tcg_temp_new();
403: dec10_reg_prep_sext(dc, size, sext,
404: t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
405:
406: if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) {
407: tcg_gen_andi_tl(t[1], t[1], 63);
408: }
409:
410: assert(dc->dst != 15);
411: cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size);
412: tcg_temp_free(t[0]);
413: tcg_temp_free(t[1]);
414: }
415:
416: static void dec10_reg_bound(DisasContext *dc, int size)
417: {
418: TCGv t;
419:
420: t = tcg_temp_local_new();
421: t_gen_zext(t, cpu_R[dc->src], size);
422: cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
423: tcg_temp_free(t);
424: }
425:
426: static void dec10_reg_mul(DisasContext *dc, int size, int sext)
427: {
428: int op = sext ? CC_OP_MULS : CC_OP_MULU;
429: TCGv t[2];
430:
431: t[0] = tcg_temp_new();
432: t[1] = tcg_temp_new();
433: dec10_reg_prep_sext(dc, size, sext,
434: t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
435:
436: cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4);
437:
438: tcg_temp_free(t[0]);
439: tcg_temp_free(t[1]);
440: }
441:
442:
443: static void dec10_reg_movs(DisasContext *dc)
444: {
445: int size = (dc->size & 1) + 1;
446: TCGv t;
447:
448: LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
449: cris_cc_mask(dc, CC_MASK_NZVC);
450:
451: t = tcg_temp_new();
452: if (dc->ir & 32)
453: t_gen_sext(t, cpu_R[dc->src], size);
454: else
455: t_gen_zext(t, cpu_R[dc->src], size);
456:
457: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
458: tcg_temp_free(t);
459: }
460:
461: static void dec10_reg_alux(DisasContext *dc, int op)
462: {
463: int size = (dc->size & 1) + 1;
464: TCGv t;
465:
466: LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
467: cris_cc_mask(dc, CC_MASK_NZVC);
468:
469: t = tcg_temp_new();
470: if (dc->ir & 32)
471: t_gen_sext(t, cpu_R[dc->src], size);
472: else
473: t_gen_zext(t, cpu_R[dc->src], size);
474:
475: cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
476: tcg_temp_free(t);
477: }
478:
479: static void dec10_reg_mov_pr(DisasContext *dc)
480: {
481: LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]);
482: cris_lock_irq(dc);
483: if (dc->src == 15) {
484: tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]);
485: cris_prepare_jmp(dc, JMP_INDIRECT);
486: return;
487: }
488: if (dc->dst == PR_CCS) {
489: cris_evaluate_flags(dc);
490: }
491: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src],
492: cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]);
493: }
494:
495: static void dec10_reg_abs(DisasContext *dc)
496: {
497: TCGv t0;
498:
499: LOG_DIS("abs $r%u, $r%u\n", dc->src, dc->dst);
500:
501: assert(dc->dst != 15);
502: t0 = tcg_temp_new();
503: tcg_gen_sari_tl(t0, cpu_R[dc->src], 31);
504: tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0);
505: tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0);
506:
507: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t0, 4);
508: tcg_temp_free(t0);
509: }
510:
511: static void dec10_reg_swap(DisasContext *dc)
512: {
513: TCGv t0;
514:
515: LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst);
516:
517: cris_cc_mask(dc, CC_MASK_NZVC);
518: t0 = tcg_temp_new();
519: t_gen_mov_TN_reg(t0, dc->src);
520: if (dc->dst & 8)
521: tcg_gen_not_tl(t0, t0);
522: if (dc->dst & 4)
523: t_gen_swapw(t0, t0);
524: if (dc->dst & 2)
525: t_gen_swapb(t0, t0);
526: if (dc->dst & 1)
527: t_gen_swapr(t0, t0);
528: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4);
529: tcg_temp_free(t0);
530: }
531:
532: static void dec10_reg_scc(DisasContext *dc)
533: {
534: int cond = dc->dst;
535:
536: LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src);
537:
538: if (cond != CC_A)
539: {
540: int l1;
541:
542: gen_tst_cc (dc, cpu_R[dc->src], cond);
543: l1 = gen_new_label();
544: tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1);
545: tcg_gen_movi_tl(cpu_R[dc->src], 1);
546: gen_set_label(l1);
547: } else {
548: tcg_gen_movi_tl(cpu_R[dc->src], 1);
549: }
550:
551: cris_cc_mask(dc, 0);
552: }
553:
554: static unsigned int dec10_reg(DisasContext *dc)
555: {
556: TCGv t;
557: unsigned int insn_len = 2;
558: unsigned int size = dec10_size(dc->size);
559: unsigned int tmp;
560:
561: if (dc->size != 3) {
562: switch (dc->opcode) {
563: case CRISV10_REG_MOVE_R:
564: LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst);
565: cris_cc_mask(dc, CC_MASK_NZVC);
566: dec10_reg_alu(dc, CC_OP_MOVE, size, 0);
567: if (dc->dst == 15) {
568: tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
569: cris_prepare_jmp(dc, JMP_INDIRECT);
570: dc->delayed_branch = 1;
571: }
572: break;
573: case CRISV10_REG_MOVX:
574: cris_cc_mask(dc, CC_MASK_NZVC);
575: dec10_reg_movs(dc);
576: break;
577: case CRISV10_REG_ADDX:
578: cris_cc_mask(dc, CC_MASK_NZVC);
579: dec10_reg_alux(dc, CC_OP_ADD);
580: break;
581: case CRISV10_REG_SUBX:
582: cris_cc_mask(dc, CC_MASK_NZVC);
583: dec10_reg_alux(dc, CC_OP_SUB);
584: break;
585: case CRISV10_REG_ADD:
586: LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
587: cris_cc_mask(dc, CC_MASK_NZVC);
588: dec10_reg_alu(dc, CC_OP_ADD, size, 0);
589: break;
590: case CRISV10_REG_SUB:
591: LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
592: cris_cc_mask(dc, CC_MASK_NZVC);
593: dec10_reg_alu(dc, CC_OP_SUB, size, 0);
594: break;
595: case CRISV10_REG_CMP:
596: LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
597: cris_cc_mask(dc, CC_MASK_NZVC);
598: dec10_reg_alu(dc, CC_OP_CMP, size, 0);
599: break;
600: case CRISV10_REG_BOUND:
601: LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
602: cris_cc_mask(dc, CC_MASK_NZVC);
603: dec10_reg_bound(dc, size);
604: break;
605: case CRISV10_REG_AND:
606: LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
607: cris_cc_mask(dc, CC_MASK_NZVC);
608: dec10_reg_alu(dc, CC_OP_AND, size, 0);
609: break;
610: case CRISV10_REG_ADDI:
611: if (dc->src == 15) {
612: /* nop. */
613: return 2;
614: }
615: t = tcg_temp_new();
616: LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size);
617: tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3);
618: tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t);
619: tcg_temp_free(t);
620: break;
621: case CRISV10_REG_LSL:
622: LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
623: cris_cc_mask(dc, CC_MASK_NZVC);
624: dec10_reg_alu(dc, CC_OP_LSL, size, 0);
625: break;
626: case CRISV10_REG_LSR:
627: LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
628: cris_cc_mask(dc, CC_MASK_NZVC);
629: dec10_reg_alu(dc, CC_OP_LSR, size, 0);
630: break;
631: case CRISV10_REG_ASR:
632: LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
633: cris_cc_mask(dc, CC_MASK_NZVC);
634: dec10_reg_alu(dc, CC_OP_ASR, size, 1);
635: break;
636: case CRISV10_REG_OR:
637: LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
638: cris_cc_mask(dc, CC_MASK_NZVC);
639: dec10_reg_alu(dc, CC_OP_OR, size, 0);
640: break;
641: case CRISV10_REG_NEG:
642: LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
643: cris_cc_mask(dc, CC_MASK_NZVC);
644: dec10_reg_alu(dc, CC_OP_NEG, size, 0);
645: break;
646: case CRISV10_REG_BIAP:
647: LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc,
648: dc->opcode, dc->src, dc->dst, size);
649: switch (size) {
650: case 4: tmp = 2; break;
651: case 2: tmp = 1; break;
652: case 1: tmp = 0; break;
653: default:
654: cpu_abort(dc->env, "Unhandled BIAP");
655: break;
656: }
657:
658: t = tcg_temp_new();
659: tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp);
660: if (dc->src == 15) {
661: tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1);
662: } else {
663: tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t);
664: }
665: tcg_temp_free(t);
666: cris_set_prefix(dc);
667: break;
668:
669: default:
670: LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
671: dc->opcode, dc->src, dc->dst);
672: cpu_abort(dc->env, "Unhandled opcode");
673: break;
674: }
675: } else {
676: switch (dc->opcode) {
677: case CRISV10_REG_MOVX:
678: cris_cc_mask(dc, CC_MASK_NZVC);
679: dec10_reg_movs(dc);
680: break;
681: case CRISV10_REG_ADDX:
682: cris_cc_mask(dc, CC_MASK_NZVC);
683: dec10_reg_alux(dc, CC_OP_ADD);
684: break;
685: case CRISV10_REG_SUBX:
686: cris_cc_mask(dc, CC_MASK_NZVC);
687: dec10_reg_alux(dc, CC_OP_SUB);
688: break;
689: case CRISV10_REG_MOVE_SPR_R:
690: cris_evaluate_flags(dc);
691: cris_cc_mask(dc, 0);
692: dec10_reg_mov_pr(dc);
693: break;
694: case CRISV10_REG_MOVE_R_SPR:
695: LOG_DIS("move r%d p%d\n", dc->src, dc->dst);
696: cris_evaluate_flags(dc);
697: if (dc->src != 11) /* fast for srp. */
698: dc->cpustate_changed = 1;
699: t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]);
700: break;
701: case CRISV10_REG_SETF:
702: case CRISV10_REG_CLEARF:
703: dec10_setclrf(dc);
704: break;
705: case CRISV10_REG_SWAP:
706: dec10_reg_swap(dc);
707: break;
708: case CRISV10_REG_ABS:
709: cris_cc_mask(dc, CC_MASK_NZVC);
710: dec10_reg_abs(dc);
711: break;
712: case CRISV10_REG_LZ:
713: LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
714: cris_cc_mask(dc, CC_MASK_NZVC);
715: dec10_reg_alu(dc, CC_OP_LZ, 4, 0);
716: break;
717: case CRISV10_REG_XOR:
718: LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
719: cris_cc_mask(dc, CC_MASK_NZVC);
720: dec10_reg_alu(dc, CC_OP_XOR, 4, 0);
721: break;
722: case CRISV10_REG_BTST:
723: LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
724: cris_cc_mask(dc, CC_MASK_NZVC);
725: cris_update_cc_op(dc, CC_OP_FLAGS, 4);
726: gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
727: cpu_R[dc->src], cpu_PR[PR_CCS]);
728: break;
729: case CRISV10_REG_DSTEP:
730: LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
731: cris_cc_mask(dc, CC_MASK_NZVC);
732: cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst],
733: cpu_R[dc->dst], cpu_R[dc->src], 4);
734: break;
735: case CRISV10_REG_MSTEP:
736: LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
737: cris_evaluate_flags(dc);
738: cris_cc_mask(dc, CC_MASK_NZVC);
739: cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst],
740: cpu_R[dc->dst], cpu_R[dc->src], 4);
741: break;
742: case CRISV10_REG_SCC:
743: dec10_reg_scc(dc);
744: break;
745: default:
746: LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
747: dc->opcode, dc->src, dc->dst);
748: cpu_abort(dc->env, "Unhandled opcode");
749: break;
750: }
751: }
752: return insn_len;
753: }
754:
755: static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
756: {
757: unsigned int insn_len = 2;
758: TCGv t;
759:
760: LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__,
761: size, dc->src, dc->dst);
762:
763: cris_cc_mask(dc, CC_MASK_NZVC);
764: t = tcg_temp_new();
765: insn_len += dec10_prep_move_m(dc, 0, size, t);
766: cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
767: if (dc->dst == 15) {
768: tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
769: cris_prepare_jmp(dc, JMP_INDIRECT);
770: dc->delayed_branch = 1;
771: return insn_len;
772: }
773:
774: tcg_temp_free(t);
775: return insn_len;
776: }
777:
778: static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
779: {
780: unsigned int insn_len = 2;
781: TCGv addr;
782:
783: LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
784: addr = tcg_temp_new();
785: crisv10_prepare_memaddr(dc, addr, size);
1.1.1.4 root 786: gen_store_v10(dc, addr, cpu_R[dc->dst], size);
1.1 root 787: insn_len += crisv10_post_memaddr(dc, size);
788:
789: return insn_len;
790: }
791:
792: static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
793: {
794: unsigned int insn_len = 2, rd = dc->dst;
795: TCGv t, addr;
796:
797: LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
798: cris_lock_irq(dc);
799:
800: addr = tcg_temp_new();
801: t = tcg_temp_new();
802: insn_len += dec10_prep_move_m(dc, 0, 4, t);
803: if (rd == 15) {
804: tcg_gen_mov_tl(env_btarget, t);
805: cris_prepare_jmp(dc, JMP_INDIRECT);
806: dc->delayed_branch = 1;
807: return insn_len;
808: }
809:
810: tcg_gen_mov_tl(cpu_PR[rd], t);
811: dc->cpustate_changed = 1;
812: tcg_temp_free(addr);
813: tcg_temp_free(t);
814: return insn_len;
815: }
816:
817: static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
818: {
819: unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst];
820: TCGv addr, t0;
821:
822: LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
823:
824: addr = tcg_temp_new();
825: crisv10_prepare_memaddr(dc, addr, size);
826: if (dc->dst == PR_CCS) {
827: t0 = tcg_temp_new();
828: cris_evaluate_flags(dc);
829: tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
1.1.1.4 root 830: gen_store_v10(dc, addr, t0, size);
1.1 root 831: tcg_temp_free(t0);
832: } else {
1.1.1.4 root 833: gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
1.1 root 834: }
835: t0 = tcg_temp_new();
836: insn_len += crisv10_post_memaddr(dc, size);
837: cris_lock_irq(dc);
838:
839: return insn_len;
840: }
841:
842: static void dec10_movem_r_m(DisasContext *dc)
843: {
844: int i, pfix = dc->tb_flags & PFIX_FLAG;
845: TCGv addr, t0;
846:
847: LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__,
848: dc->dst, dc->src, dc->postinc, dc->ir);
849:
850: addr = tcg_temp_new();
851: t0 = tcg_temp_new();
852: crisv10_prepare_memaddr(dc, addr, 4);
853: tcg_gen_mov_tl(t0, addr);
854: for (i = dc->dst; i >= 0; i--) {
855: if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
1.1.1.4 root 856: gen_store_v10(dc, addr, t0, 4);
1.1 root 857: } else {
1.1.1.4 root 858: gen_store_v10(dc, addr, cpu_R[i], 4);
1.1 root 859: }
860: tcg_gen_addi_tl(addr, addr, 4);
861: }
862:
863: if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
864: tcg_gen_mov_tl(cpu_R[dc->src], t0);
865: }
866:
867: if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
868: tcg_gen_mov_tl(cpu_R[dc->src], addr);
869: }
870: tcg_temp_free(addr);
871: tcg_temp_free(t0);
872: }
873:
874: static void dec10_movem_m_r(DisasContext *dc)
875: {
876: int i, pfix = dc->tb_flags & PFIX_FLAG;
877: TCGv addr, t0;
878:
879: LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__,
880: dc->src, dc->dst, dc->postinc, dc->ir);
881:
882: addr = tcg_temp_new();
883: t0 = tcg_temp_new();
884: crisv10_prepare_memaddr(dc, addr, 4);
885: tcg_gen_mov_tl(t0, addr);
886: for (i = dc->dst; i >= 0; i--) {
887: gen_load(dc, cpu_R[i], addr, 4, 0);
888: tcg_gen_addi_tl(addr, addr, 4);
889: }
890:
891: if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
892: tcg_gen_mov_tl(cpu_R[dc->src], t0);
893: }
894:
895: if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
896: tcg_gen_mov_tl(cpu_R[dc->src], addr);
897: }
898: tcg_temp_free(addr);
899: tcg_temp_free(t0);
900: }
901:
902: static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
903: {
904: int insn_len = 0;
905: int rd = dc->dst;
906: TCGv t[2];
907:
908: cris_alu_m_alloc_temps(t);
909: insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
910: cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
911: if (dc->dst == 15) {
912: tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
913: cris_prepare_jmp(dc, JMP_INDIRECT);
914: dc->delayed_branch = 1;
915: return insn_len;
916: }
917:
918: cris_alu_m_free_temps(t);
919:
920: return insn_len;
921: }
922:
923: static int dec10_ind_bound(DisasContext *dc, unsigned int size)
924: {
925: int insn_len = 0;
926: int rd = dc->dst;
927: TCGv t;
928:
929: t = tcg_temp_local_new();
930: insn_len += dec10_prep_move_m(dc, 0, size, t);
931: cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
932: if (dc->dst == 15) {
933: tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
934: cris_prepare_jmp(dc, JMP_INDIRECT);
935: dc->delayed_branch = 1;
936: return insn_len;
937: }
938:
939: tcg_temp_free(t);
940: return insn_len;
941: }
942:
943: static int dec10_alux_m(DisasContext *dc, int op)
944: {
945: unsigned int size = (dc->size & 1) ? 2 : 1;
946: unsigned int sx = !!(dc->size & 2);
947: int insn_len = 2;
948: int rd = dc->dst;
949: TCGv t;
950:
951: LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst);
952:
953: t = tcg_temp_new();
954:
955: cris_cc_mask(dc, CC_MASK_NZVC);
956: insn_len += dec10_prep_move_m(dc, sx, size, t);
957: cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
958: if (dc->dst == 15) {
959: tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
960: cris_prepare_jmp(dc, JMP_INDIRECT);
961: dc->delayed_branch = 1;
962: return insn_len;
963: }
964:
965: tcg_temp_free(t);
966: return insn_len;
967: }
968:
969: static int dec10_dip(DisasContext *dc)
970: {
971: int insn_len = 2;
972: uint32_t imm;
973:
974: LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
975: dc->pc, dc->opcode, dc->src, dc->dst);
976: if (dc->src == 15) {
977: imm = ldl_code(dc->pc + 2);
978: tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
979: if (dc->postinc)
980: insn_len += 4;
981: tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2);
982: } else {
983: gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0);
984: if (dc->postinc)
985: tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4);
986: }
987:
988: cris_set_prefix(dc);
989: return insn_len;
990: }
991:
992: static int dec10_bdap_m(DisasContext *dc, int size)
993: {
994: int insn_len = 2;
995: int rd = dc->dst;
996:
997: LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n",
998: dc->pc, dc->opcode, dc->src, dc->dst, size);
999:
1000: assert(dc->dst != 15);
1001: #if 0
1002: /* 8bit embedded offset? */
1003: if (!dc->postinc && (dc->ir & (1 << 11))) {
1004: int simm = dc->ir & 0xff;
1005:
1006: /* cpu_abort(dc->env, "Unhandled opcode"); */
1007: /* sign extended. */
1008: simm = (int8_t)simm;
1009:
1010: tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
1011:
1012: cris_set_prefix(dc);
1013: return insn_len;
1014: }
1015: #endif
1.1.1.3 root 1016: /* Now the rest of the modes are truly indirect. */
1.1 root 1017: insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]);
1018: tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
1019: cris_set_prefix(dc);
1020: return insn_len;
1021: }
1022:
1023: static unsigned int dec10_ind(DisasContext *dc)
1024: {
1025: unsigned int insn_len = 2;
1026: unsigned int size = dec10_size(dc->size);
1027: uint32_t imm;
1028: int32_t simm;
1029: TCGv t[2];
1030:
1031: if (dc->size != 3) {
1032: switch (dc->opcode) {
1033: case CRISV10_IND_MOVE_M_R:
1034: return dec10_ind_move_m_r(dc, size);
1035: break;
1036: case CRISV10_IND_MOVE_R_M:
1037: return dec10_ind_move_r_m(dc, size);
1038: break;
1039: case CRISV10_IND_CMP:
1040: LOG_DIS("cmp size=%d op=%d %d\n", size, dc->src, dc->dst);
1041: cris_cc_mask(dc, CC_MASK_NZVC);
1042: insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
1043: break;
1044: case CRISV10_IND_TEST:
1045: LOG_DIS("test size=%d op=%d %d\n", size, dc->src, dc->dst);
1046:
1047: cris_evaluate_flags(dc);
1048: cris_cc_mask(dc, CC_MASK_NZVC);
1049: cris_alu_m_alloc_temps(t);
1050: insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
1051: tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
1052: cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
1053: t[0], tcg_const_tl(0), size);
1054: cris_alu_m_free_temps(t);
1055: break;
1056: case CRISV10_IND_ADD:
1057: LOG_DIS("add size=%d op=%d %d\n", size, dc->src, dc->dst);
1058: cris_cc_mask(dc, CC_MASK_NZVC);
1059: insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
1060: break;
1061: case CRISV10_IND_SUB:
1062: LOG_DIS("sub size=%d op=%d %d\n", size, dc->src, dc->dst);
1063: cris_cc_mask(dc, CC_MASK_NZVC);
1064: insn_len += dec10_ind_alu(dc, CC_OP_SUB, size);
1065: break;
1066: case CRISV10_IND_BOUND:
1067: LOG_DIS("bound size=%d op=%d %d\n", size, dc->src, dc->dst);
1068: cris_cc_mask(dc, CC_MASK_NZVC);
1069: insn_len += dec10_ind_bound(dc, size);
1070: break;
1071: case CRISV10_IND_AND:
1072: LOG_DIS("and size=%d op=%d %d\n", size, dc->src, dc->dst);
1073: cris_cc_mask(dc, CC_MASK_NZVC);
1074: insn_len += dec10_ind_alu(dc, CC_OP_AND, size);
1075: break;
1076: case CRISV10_IND_OR:
1077: LOG_DIS("or size=%d op=%d %d\n", size, dc->src, dc->dst);
1078: cris_cc_mask(dc, CC_MASK_NZVC);
1079: insn_len += dec10_ind_alu(dc, CC_OP_OR, size);
1080: break;
1081: case CRISV10_IND_MOVX:
1082: insn_len = dec10_alux_m(dc, CC_OP_MOVE);
1083: break;
1084: case CRISV10_IND_ADDX:
1085: insn_len = dec10_alux_m(dc, CC_OP_ADD);
1086: break;
1087: case CRISV10_IND_SUBX:
1088: insn_len = dec10_alux_m(dc, CC_OP_SUB);
1089: break;
1090: case CRISV10_IND_CMPX:
1091: insn_len = dec10_alux_m(dc, CC_OP_CMP);
1092: break;
1093: case CRISV10_IND_MUL:
1094: /* This is a reg insn coded in the mem indir space. */
1095: LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode);
1096: cris_cc_mask(dc, CC_MASK_NZVC);
1097: dec10_reg_mul(dc, size, dc->ir & (1 << 10));
1098: break;
1099: case CRISV10_IND_BDAP_M:
1100: insn_len = dec10_bdap_m(dc, size);
1101: break;
1102: default:
1103: LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
1104: dc->pc, size, dc->opcode, dc->src, dc->dst);
1105: cpu_abort(dc->env, "Unhandled opcode");
1106: break;
1107: }
1108: return insn_len;
1109: }
1110:
1111: switch (dc->opcode) {
1112: case CRISV10_IND_MOVE_M_SPR:
1113: insn_len = dec10_ind_move_m_pr(dc);
1114: break;
1115: case CRISV10_IND_MOVE_SPR_M:
1116: insn_len = dec10_ind_move_pr_m(dc);
1117: break;
1118: case CRISV10_IND_JUMP_M:
1119: if (dc->src == 15) {
1.1.1.2 root 1120: LOG_DIS("jump.%d %d r%d r%d direct\n", size,
1.1 root 1121: dc->opcode, dc->src, dc->dst);
1122: imm = ldl_code(dc->pc + 2);
1123: if (dc->mode == CRISV10_MODE_AUTOINC)
1124: insn_len += size;
1125:
1126: t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1.1.1.2 root 1127: dc->jmp_pc = imm;
1128: cris_prepare_jmp(dc, JMP_DIRECT);
1.1 root 1129: dc->delayed_branch--; /* v10 has no dslot here. */
1130: } else {
1131: if (dc->dst == 14) {
1132: LOG_DIS("break %d\n", dc->src);
1133: cris_evaluate_flags(dc);
1134: tcg_gen_movi_tl(env_pc, dc->pc + 2);
1135: t_gen_raise_exception(EXCP_BREAK);
1136: dc->is_jmp = DISAS_UPDATE;
1137: return insn_len;
1138: }
1139: LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
1140: dc->opcode, dc->src, dc->dst);
1141: t[0] = tcg_temp_new();
1142: t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1143: crisv10_prepare_memaddr(dc, t[0], size);
1144: gen_load(dc, env_btarget, t[0], 4, 0);
1145: insn_len += crisv10_post_memaddr(dc, size);
1146: cris_prepare_jmp(dc, JMP_INDIRECT);
1147: dc->delayed_branch--; /* v10 has no dslot here. */
1148: tcg_temp_free(t[0]);
1149: }
1150: break;
1151:
1152: case CRISV10_IND_MOVEM_R_M:
1153: LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n",
1154: dc->pc, dc->opcode, dc->dst, dc->src);
1155: dec10_movem_r_m(dc);
1156: break;
1157: case CRISV10_IND_MOVEM_M_R:
1158: LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode);
1159: dec10_movem_m_r(dc);
1160: break;
1161: case CRISV10_IND_JUMP_R:
1162: LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n",
1163: dc->pc, dc->opcode, dc->dst, dc->src);
1164: tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]);
1165: t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
1166: cris_prepare_jmp(dc, JMP_INDIRECT);
1167: dc->delayed_branch--; /* v10 has no dslot here. */
1168: break;
1169: case CRISV10_IND_MOVX:
1170: insn_len = dec10_alux_m(dc, CC_OP_MOVE);
1171: break;
1172: case CRISV10_IND_ADDX:
1173: insn_len = dec10_alux_m(dc, CC_OP_ADD);
1174: break;
1175: case CRISV10_IND_SUBX:
1176: insn_len = dec10_alux_m(dc, CC_OP_SUB);
1177: break;
1178: case CRISV10_IND_CMPX:
1179: insn_len = dec10_alux_m(dc, CC_OP_CMP);
1180: break;
1181: case CRISV10_IND_DIP:
1182: insn_len = dec10_dip(dc);
1183: break;
1184: case CRISV10_IND_BCC_M:
1185:
1186: cris_cc_mask(dc, 0);
1187: imm = ldsw_code(dc->pc + 2);
1188: simm = (int16_t)imm;
1189: simm += 4;
1190:
1191: LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm);
1192: cris_prepare_cc_branch(dc, simm, dc->cond);
1193: insn_len = 4;
1194: break;
1195: default:
1196: LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode);
1197: cpu_abort(dc->env, "Unhandled opcode");
1198: break;
1199: }
1200:
1201: return insn_len;
1202: }
1203:
1204: static unsigned int crisv10_decoder(DisasContext *dc)
1205: {
1206: unsigned int insn_len = 2;
1207:
1208: if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1209: tcg_gen_debug_insn_start(dc->pc);
1210:
1211: /* Load a halfword onto the instruction register. */
1212: dc->ir = lduw_code(dc->pc);
1213:
1214: /* Now decode it. */
1215: dc->opcode = EXTRACT_FIELD(dc->ir, 6, 9);
1216: dc->mode = EXTRACT_FIELD(dc->ir, 10, 11);
1217: dc->src = EXTRACT_FIELD(dc->ir, 0, 3);
1218: dc->size = EXTRACT_FIELD(dc->ir, 4, 5);
1219: dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15);
1220: dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
1221:
1222: dc->clear_prefix = 1;
1223:
1224: /* FIXME: What if this insn insn't 2 in length?? */
1225: if (dc->src == 15 || dc->dst == 15)
1226: tcg_gen_movi_tl(cpu_R[15], dc->pc + 2);
1227:
1228: switch (dc->mode) {
1229: case CRISV10_MODE_QIMMEDIATE:
1230: insn_len = dec10_quick_imm(dc);
1231: break;
1232: case CRISV10_MODE_REG:
1233: insn_len = dec10_reg(dc);
1234: break;
1235: case CRISV10_MODE_AUTOINC:
1236: case CRISV10_MODE_INDIRECT:
1237: insn_len = dec10_ind(dc);
1238: break;
1239: }
1240:
1241: if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) {
1242: dc->tb_flags &= ~PFIX_FLAG;
1243: tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG);
1.1.1.2 root 1244: if (dc->tb_flags != dc->tb->flags) {
1245: dc->cpustate_changed = 1;
1246: }
1.1 root 1247: }
1248:
1249: /* CRISv10 locks out interrupts on dslots. */
1250: if (dc->delayed_branch == 2) {
1251: cris_lock_irq(dc);
1252: }
1253: return insn_len;
1254: }
1255:
1.1.1.5 ! root 1256: static CPUCRISState *cpu_crisv10_init (CPUCRISState *env)
1.1 root 1257: {
1258: int i;
1259:
1260: cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1261: cc_x = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1262: offsetof(CPUCRISState, cc_x), "cc_x");
1.1 root 1263: cc_src = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1264: offsetof(CPUCRISState, cc_src), "cc_src");
1.1 root 1265: cc_dest = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1266: offsetof(CPUCRISState, cc_dest),
1.1 root 1267: "cc_dest");
1268: cc_result = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1269: offsetof(CPUCRISState, cc_result),
1.1 root 1270: "cc_result");
1271: cc_op = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1272: offsetof(CPUCRISState, cc_op), "cc_op");
1.1 root 1273: cc_size = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1274: offsetof(CPUCRISState, cc_size),
1.1 root 1275: "cc_size");
1276: cc_mask = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1277: offsetof(CPUCRISState, cc_mask),
1.1 root 1278: "cc_mask");
1279:
1280: env_pc = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1281: offsetof(CPUCRISState, pc),
1.1 root 1282: "pc");
1283: env_btarget = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1284: offsetof(CPUCRISState, btarget),
1.1 root 1285: "btarget");
1286: env_btaken = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1287: offsetof(CPUCRISState, btaken),
1.1 root 1288: "btaken");
1289: for (i = 0; i < 16; i++) {
1290: cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1291: offsetof(CPUCRISState, regs[i]),
1.1 root 1292: regnames_v10[i]);
1293: }
1294: for (i = 0; i < 16; i++) {
1295: cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.5 ! root 1296: offsetof(CPUCRISState, pregs[i]),
1.1 root 1297: pregnames_v10[i]);
1298: }
1299:
1300: return env;
1301: }
1302:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.