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