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