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