1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25
26#include "cpu.h"
27#include "exec/exec-all.h"
28#include "disas/disas.h"
29#include "tcg-op.h"
30#include "exec/cpu_ldst.h"
31
32#include "exec/helper-proto.h"
33#include "exec/helper-gen.h"
34#include "exec/log.h"
35
36
37typedef struct DisasContext {
38 struct TranslationBlock *tb;
39 target_ulong pc, saved_pc;
40 uint32_t opcode;
41 uint32_t fp_status;
42
43 int memidx;
44 int bstate;
45 target_ulong btarget;
46 int singlestep_enabled;
47} DisasContext;
48
49enum {
50 BS_NONE = 0,
51
52 BS_STOP = 1,
53 BS_BRANCH = 2,
54 BS_EXCP = 3,
55};
56
57static TCGv cpu_pc;
58static TCGv cpu_gregs[16];
59static TCGv_env cpu_env;
60static TCGv cc_a, cc_b;
61
62#include "exec/gen-icount.h"
63
64#define REG(x) (cpu_gregs[x])
65
66
67
68static int extract_branch_offset(int opcode)
69{
70 return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
71}
72
73void moxie_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
74 int flags)
75{
76 MoxieCPU *cpu = MOXIE_CPU(cs);
77 CPUMoxieState *env = &cpu->env;
78 int i;
79 cpu_fprintf(f, "pc=0x%08x\n", env->pc);
80 cpu_fprintf(f, "$fp=0x%08x $sp=0x%08x $r0=0x%08x $r1=0x%08x\n",
81 env->gregs[0], env->gregs[1], env->gregs[2], env->gregs[3]);
82 for (i = 4; i < 16; i += 4) {
83 cpu_fprintf(f, "$r%d=0x%08x $r%d=0x%08x $r%d=0x%08x $r%d=0x%08x\n",
84 i-2, env->gregs[i], i-1, env->gregs[i + 1],
85 i, env->gregs[i + 2], i+1, env->gregs[i + 3]);
86 }
87 for (i = 4; i < 16; i += 4) {
88 cpu_fprintf(f, "sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x\n",
89 i-2, env->sregs[i], i-1, env->sregs[i + 1],
90 i, env->sregs[i + 2], i+1, env->sregs[i + 3]);
91 }
92}
93
94void moxie_translate_init(void)
95{
96 int i;
97 static int done_init;
98 static const char * const gregnames[16] = {
99 "$fp", "$sp", "$r0", "$r1",
100 "$r2", "$r3", "$r4", "$r5",
101 "$r6", "$r7", "$r8", "$r9",
102 "$r10", "$r11", "$r12", "$r13"
103 };
104
105 if (done_init) {
106 return;
107 }
108 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
109 cpu_pc = tcg_global_mem_new_i32(cpu_env,
110 offsetof(CPUMoxieState, pc), "$pc");
111 for (i = 0; i < 16; i++)
112 cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
113 offsetof(CPUMoxieState, gregs[i]),
114 gregnames[i]);
115
116 cc_a = tcg_global_mem_new_i32(cpu_env,
117 offsetof(CPUMoxieState, cc_a), "cc_a");
118 cc_b = tcg_global_mem_new_i32(cpu_env,
119 offsetof(CPUMoxieState, cc_b), "cc_b");
120
121 done_init = 1;
122}
123
124static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
125 int n, target_ulong dest)
126{
127 TranslationBlock *tb;
128 tb = ctx->tb;
129
130 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
131 !ctx->singlestep_enabled) {
132 tcg_gen_goto_tb(n);
133 tcg_gen_movi_i32(cpu_pc, dest);
134 tcg_gen_exit_tb((uintptr_t)tb + n);
135 } else {
136 tcg_gen_movi_i32(cpu_pc, dest);
137 if (ctx->singlestep_enabled) {
138 gen_helper_debug(cpu_env);
139 }
140 tcg_gen_exit_tb(0);
141 }
142}
143
144static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
145{
146 CPUMoxieState *env = &cpu->env;
147
148
149 int opcode;
150
151 int length = 2;
152
153
154 opcode = ctx->opcode;
155
156
157 if (opcode & (1 << 15)) {
158 if (opcode & (1 << 14)) {
159
160 int inst = (opcode >> 10 & 0xf);
161
162#define BRANCH(cond) \
163 do { \
164 TCGLabel *l1 = gen_new_label(); \
165 tcg_gen_brcond_i32(cond, cc_a, cc_b, l1); \
166 gen_goto_tb(env, ctx, 1, ctx->pc+2); \
167 gen_set_label(l1); \
168 gen_goto_tb(env, ctx, 0, extract_branch_offset(opcode) + ctx->pc+2); \
169 ctx->bstate = BS_BRANCH; \
170 } while (0)
171
172 switch (inst) {
173 case 0x00:
174 BRANCH(TCG_COND_EQ);
175 break;
176 case 0x01:
177 BRANCH(TCG_COND_NE);
178 break;
179 case 0x02:
180 BRANCH(TCG_COND_LT);
181 break;
182 case 0x03:
183 BRANCH(TCG_COND_GT);
184 break;
185 case 0x04:
186 BRANCH(TCG_COND_LTU);
187 break;
188 case 0x05:
189 BRANCH(TCG_COND_GTU);
190 break;
191 case 0x06:
192 BRANCH(TCG_COND_GE);
193 break;
194 case 0x07:
195 BRANCH(TCG_COND_LE);
196 break;
197 case 0x08:
198 BRANCH(TCG_COND_GEU);
199 break;
200 case 0x09:
201 BRANCH(TCG_COND_LEU);
202 break;
203 default:
204 {
205 TCGv temp = tcg_temp_new_i32();
206 tcg_gen_movi_i32(cpu_pc, ctx->pc);
207 tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
208 gen_helper_raise_exception(cpu_env, temp);
209 tcg_temp_free_i32(temp);
210 }
211 break;
212 }
213 } else {
214
215 int inst = (opcode >> 12 & 0x3);
216 switch (inst) {
217 case 0x00:
218 {
219 int a = (opcode >> 8) & 0xf;
220 unsigned int v = (opcode & 0xff);
221 tcg_gen_addi_i32(REG(a), REG(a), v);
222 }
223 break;
224 case 0x01:
225 {
226 int a = (opcode >> 8) & 0xf;
227 unsigned int v = (opcode & 0xff);
228 tcg_gen_subi_i32(REG(a), REG(a), v);
229 }
230 break;
231 case 0x02:
232 {
233 int a = (opcode >> 8) & 0xf;
234 unsigned v = (opcode & 0xff);
235 tcg_gen_ld_i32(REG(a), cpu_env,
236 offsetof(CPUMoxieState, sregs[v]));
237 }
238 break;
239 case 0x03:
240 {
241 int a = (opcode >> 8) & 0xf;
242 unsigned v = (opcode & 0xff);
243 tcg_gen_st_i32(REG(a), cpu_env,
244 offsetof(CPUMoxieState, sregs[v]));
245 }
246 break;
247 default:
248 {
249 TCGv temp = tcg_temp_new_i32();
250 tcg_gen_movi_i32(cpu_pc, ctx->pc);
251 tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
252 gen_helper_raise_exception(cpu_env, temp);
253 tcg_temp_free_i32(temp);
254 }
255 break;
256 }
257 }
258 } else {
259
260 int inst = opcode >> 8;
261 switch (inst) {
262 case 0x00:
263 break;
264 case 0x01:
265 {
266 int reg = (opcode >> 4) & 0xf;
267 int val = cpu_ldl_code(env, ctx->pc+2);
268 tcg_gen_movi_i32(REG(reg), val);
269 length = 6;
270 }
271 break;
272 case 0x02:
273 {
274 int dest = (opcode >> 4) & 0xf;
275 int src = opcode & 0xf;
276 tcg_gen_mov_i32(REG(dest), REG(src));
277 }
278 break;
279 case 0x03:
280 {
281 TCGv t1 = tcg_temp_new_i32();
282 TCGv t2 = tcg_temp_new_i32();
283
284 tcg_gen_movi_i32(t1, ctx->pc + 6);
285
286
287 tcg_gen_subi_i32(t2, REG(1), 8);
288 tcg_gen_mov_i32(REG(1), t2);
289 tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
290
291
292 tcg_gen_subi_i32(t2, REG(1), 4);
293 tcg_gen_mov_i32(REG(1), t2);
294 tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
295
296
297 tcg_gen_mov_i32(REG(0), REG(1));
298
299 gen_goto_tb(env, ctx, 0, cpu_ldl_code(env, ctx->pc+2));
300
301 tcg_temp_free_i32(t1);
302 tcg_temp_free_i32(t2);
303
304 ctx->bstate = BS_BRANCH;
305 length = 6;
306 }
307 break;
308 case 0x04:
309 {
310 TCGv t1 = tcg_temp_new_i32();
311
312
313 tcg_gen_mov_i32(REG(1), REG(0));
314
315
316 tcg_gen_qemu_ld32u(REG(0), REG(1), ctx->memidx);
317 tcg_gen_addi_i32(t1, REG(1), 4);
318 tcg_gen_mov_i32(REG(1), t1);
319
320
321
322
323 tcg_gen_qemu_ld32u(cpu_pc, REG(1), ctx->memidx);
324 tcg_gen_addi_i32(t1, REG(1), 8);
325 tcg_gen_mov_i32(REG(1), t1);
326
327 tcg_temp_free_i32(t1);
328
329
330 tcg_gen_exit_tb(0);
331
332 ctx->bstate = BS_BRANCH;
333 }
334 break;
335 case 0x05:
336 {
337 int a = (opcode >> 4) & 0xf;
338 int b = opcode & 0xf;
339
340 tcg_gen_add_i32(REG(a), REG(a), REG(b));
341 }
342 break;
343 case 0x06:
344 {
345 int a = (opcode >> 4) & 0xf;
346 int b = opcode & 0xf;
347
348 TCGv t1 = tcg_temp_new_i32();
349 tcg_gen_subi_i32(t1, REG(a), 4);
350 tcg_gen_mov_i32(REG(a), t1);
351 tcg_gen_qemu_st32(REG(b), REG(a), ctx->memidx);
352 tcg_temp_free_i32(t1);
353 }
354 break;
355 case 0x07:
356 {
357 int a = (opcode >> 4) & 0xf;
358 int b = opcode & 0xf;
359 TCGv t1 = tcg_temp_new_i32();
360
361 tcg_gen_qemu_ld32u(REG(b), REG(a), ctx->memidx);
362 tcg_gen_addi_i32(t1, REG(a), 4);
363 tcg_gen_mov_i32(REG(a), t1);
364 tcg_temp_free_i32(t1);
365 }
366 break;
367 case 0x08:
368 {
369 int reg = (opcode >> 4) & 0xf;
370
371 TCGv ptr = tcg_temp_new_i32();
372 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
373 tcg_gen_qemu_ld32u(REG(reg), ptr, ctx->memidx);
374 tcg_temp_free_i32(ptr);
375
376 length = 6;
377 }
378 break;
379 case 0x09:
380 {
381 int val = (opcode >> 4) & 0xf;
382
383 TCGv ptr = tcg_temp_new_i32();
384 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
385 tcg_gen_qemu_st32(REG(val), ptr, ctx->memidx);
386 tcg_temp_free_i32(ptr);
387
388 length = 6;
389 }
390 break;
391 case 0x0a:
392 {
393 int src = opcode & 0xf;
394 int dest = (opcode >> 4) & 0xf;
395
396 tcg_gen_qemu_ld32u(REG(dest), REG(src), ctx->memidx);
397 }
398 break;
399 case 0x0b:
400 {
401 int dest = (opcode >> 4) & 0xf;
402 int val = opcode & 0xf;
403
404 tcg_gen_qemu_st32(REG(val), REG(dest), ctx->memidx);
405 }
406 break;
407 case 0x0c:
408 {
409 int a = (opcode >> 4) & 0xf;
410 int b = opcode & 0xf;
411
412 TCGv t1 = tcg_temp_new_i32();
413 TCGv t2 = tcg_temp_new_i32();
414 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
415 tcg_gen_qemu_ld32u(t2, t1, ctx->memidx);
416 tcg_gen_mov_i32(REG(a), t2);
417
418 tcg_temp_free_i32(t1);
419 tcg_temp_free_i32(t2);
420
421 length = 6;
422 }
423 break;
424 case 0x0d:
425 {
426 int a = (opcode >> 4) & 0xf;
427 int b = opcode & 0xf;
428
429 TCGv t1 = tcg_temp_new_i32();
430 TCGv t2 = tcg_temp_new_i32();
431 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
432 tcg_gen_qemu_st32(REG(b), t1, ctx->memidx);
433
434 tcg_temp_free_i32(t1);
435 tcg_temp_free_i32(t2);
436
437 length = 6;
438 }
439 break;
440 case 0x0e:
441 {
442 int a = (opcode >> 4) & 0xf;
443 int b = opcode & 0xf;
444
445 tcg_gen_mov_i32(cc_a, REG(a));
446 tcg_gen_mov_i32(cc_b, REG(b));
447 }
448 break;
449 case 0x19:
450 {
451 int fnreg = (opcode >> 4) & 0xf;
452
453
454 TCGv t1 = tcg_temp_new_i32();
455 TCGv t2 = tcg_temp_new_i32();
456
457 tcg_gen_movi_i32(t1, ctx->pc+2);
458
459
460 tcg_gen_subi_i32(t2, REG(1), 8);
461 tcg_gen_mov_i32(REG(1), t2);
462 tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
463
464
465 tcg_gen_subi_i32(t2, REG(1), 4);
466 tcg_gen_mov_i32(REG(1), t2);
467 tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
468
469
470 tcg_gen_mov_i32(REG(0), REG(1));
471 tcg_gen_mov_i32(cpu_pc, REG(fnreg));
472 tcg_temp_free_i32(t1);
473 tcg_temp_free_i32(t2);
474 tcg_gen_exit_tb(0);
475 ctx->bstate = BS_BRANCH;
476 }
477 break;
478 case 0x1a:
479 {
480 tcg_gen_movi_i32(cpu_pc, cpu_ldl_code(env, ctx->pc+2));
481 tcg_gen_exit_tb(0);
482 ctx->bstate = BS_BRANCH;
483 length = 6;
484 }
485 break;
486 case 0x1b:
487 {
488 int reg = (opcode >> 4) & 0xf;
489 int val = cpu_ldl_code(env, ctx->pc+2);
490 tcg_gen_movi_i32(REG(reg), val);
491 length = 6;
492 }
493 break;
494 case 0x1c:
495 {
496 int src = opcode & 0xf;
497 int dest = (opcode >> 4) & 0xf;
498
499 tcg_gen_qemu_ld8u(REG(dest), REG(src), ctx->memidx);
500 }
501 break;
502 case 0x1d:
503 {
504 int reg = (opcode >> 4) & 0xf;
505
506 TCGv ptr = tcg_temp_new_i32();
507 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
508 tcg_gen_qemu_ld8u(REG(reg), ptr, ctx->memidx);
509 tcg_temp_free_i32(ptr);
510
511 length = 6;
512 }
513 break;
514 case 0x1e:
515 {
516 int dest = (opcode >> 4) & 0xf;
517 int val = opcode & 0xf;
518
519 tcg_gen_qemu_st8(REG(val), REG(dest), ctx->memidx);
520 }
521 break;
522 case 0x1f:
523 {
524 int val = (opcode >> 4) & 0xf;
525
526 TCGv ptr = tcg_temp_new_i32();
527 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
528 tcg_gen_qemu_st8(REG(val), ptr, ctx->memidx);
529 tcg_temp_free_i32(ptr);
530
531 length = 6;
532 }
533 break;
534 case 0x20:
535 {
536 int reg = (opcode >> 4) & 0xf;
537 int val = cpu_ldl_code(env, ctx->pc+2);
538 tcg_gen_movi_i32(REG(reg), val);
539 length = 6;
540 }
541 break;
542 case 0x21:
543 {
544 int src = opcode & 0xf;
545 int dest = (opcode >> 4) & 0xf;
546
547 tcg_gen_qemu_ld16u(REG(dest), REG(src), ctx->memidx);
548 }
549 break;
550 case 0x22:
551 {
552 int reg = (opcode >> 4) & 0xf;
553
554 TCGv ptr = tcg_temp_new_i32();
555 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
556 tcg_gen_qemu_ld16u(REG(reg), ptr, ctx->memidx);
557 tcg_temp_free_i32(ptr);
558
559 length = 6;
560 }
561 break;
562 case 0x23:
563 {
564 int dest = (opcode >> 4) & 0xf;
565 int val = opcode & 0xf;
566
567 tcg_gen_qemu_st16(REG(val), REG(dest), ctx->memidx);
568 }
569 break;
570 case 0x24:
571 {
572 int val = (opcode >> 4) & 0xf;
573
574 TCGv ptr = tcg_temp_new_i32();
575 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
576 tcg_gen_qemu_st16(REG(val), ptr, ctx->memidx);
577 tcg_temp_free_i32(ptr);
578
579 length = 6;
580 }
581 break;
582 case 0x25:
583 {
584 int reg = (opcode >> 4) & 0xf;
585 tcg_gen_mov_i32(cpu_pc, REG(reg));
586 tcg_gen_exit_tb(0);
587 ctx->bstate = BS_BRANCH;
588 }
589 break;
590 case 0x26:
591 {
592 int a = (opcode >> 4) & 0xf;
593 int b = opcode & 0xf;
594
595 tcg_gen_and_i32(REG(a), REG(a), REG(b));
596 }
597 break;
598 case 0x27:
599 {
600 int a = (opcode >> 4) & 0xf;
601 int b = opcode & 0xf;
602
603 TCGv sv = tcg_temp_new_i32();
604 tcg_gen_andi_i32(sv, REG(b), 0x1f);
605 tcg_gen_shr_i32(REG(a), REG(a), sv);
606 tcg_temp_free_i32(sv);
607 }
608 break;
609 case 0x28:
610 {
611 int a = (opcode >> 4) & 0xf;
612 int b = opcode & 0xf;
613
614 TCGv sv = tcg_temp_new_i32();
615 tcg_gen_andi_i32(sv, REG(b), 0x1f);
616 tcg_gen_shl_i32(REG(a), REG(a), sv);
617 tcg_temp_free_i32(sv);
618 }
619 break;
620 case 0x29:
621 {
622 int a = (opcode >> 4) & 0xf;
623 int b = opcode & 0xf;
624
625 tcg_gen_sub_i32(REG(a), REG(a), REG(b));
626 }
627 break;
628 case 0x2a:
629 {
630 int a = (opcode >> 4) & 0xf;
631 int b = opcode & 0xf;
632
633 tcg_gen_neg_i32(REG(a), REG(b));
634 }
635 break;
636 case 0x2b:
637 {
638 int a = (opcode >> 4) & 0xf;
639 int b = opcode & 0xf;
640
641 tcg_gen_or_i32(REG(a), REG(a), REG(b));
642 }
643 break;
644 case 0x2c:
645 {
646 int a = (opcode >> 4) & 0xf;
647 int b = opcode & 0xf;
648
649 tcg_gen_not_i32(REG(a), REG(b));
650 }
651 break;
652 case 0x2d:
653 {
654 int a = (opcode >> 4) & 0xf;
655 int b = opcode & 0xf;
656
657 TCGv sv = tcg_temp_new_i32();
658 tcg_gen_andi_i32(sv, REG(b), 0x1f);
659 tcg_gen_sar_i32(REG(a), REG(a), sv);
660 tcg_temp_free_i32(sv);
661 }
662 break;
663 case 0x2e:
664 {
665 int a = (opcode >> 4) & 0xf;
666 int b = opcode & 0xf;
667
668 tcg_gen_xor_i32(REG(a), REG(a), REG(b));
669 }
670 break;
671 case 0x2f:
672 {
673 int a = (opcode >> 4) & 0xf;
674 int b = opcode & 0xf;
675
676 tcg_gen_mul_i32(REG(a), REG(a), REG(b));
677 }
678 break;
679 case 0x30:
680 {
681 int val = cpu_ldl_code(env, ctx->pc+2);
682
683 TCGv temp = tcg_temp_new_i32();
684 tcg_gen_movi_i32(temp, val);
685 tcg_gen_st_i32(temp, cpu_env,
686 offsetof(CPUMoxieState, sregs[3]));
687 tcg_gen_movi_i32(cpu_pc, ctx->pc);
688 tcg_gen_movi_i32(temp, MOXIE_EX_SWI);
689 gen_helper_raise_exception(cpu_env, temp);
690 tcg_temp_free_i32(temp);
691
692 length = 6;
693 }
694 break;
695 case 0x31:
696 {
697 int a = (opcode >> 4) & 0xf;
698 int b = opcode & 0xf;
699 tcg_gen_movi_i32(cpu_pc, ctx->pc);
700 gen_helper_div(REG(a), cpu_env, REG(a), REG(b));
701 }
702 break;
703 case 0x32:
704 {
705 int a = (opcode >> 4) & 0xf;
706 int b = opcode & 0xf;
707 tcg_gen_movi_i32(cpu_pc, ctx->pc);
708 gen_helper_udiv(REG(a), cpu_env, REG(a), REG(b));
709 }
710 break;
711 case 0x33:
712 {
713 int a = (opcode >> 4) & 0xf;
714 int b = opcode & 0xf;
715 tcg_gen_rem_i32(REG(a), REG(a), REG(b));
716 }
717 break;
718 case 0x34:
719 {
720 int a = (opcode >> 4) & 0xf;
721 int b = opcode & 0xf;
722 tcg_gen_remu_i32(REG(a), REG(a), REG(b));
723 }
724 break;
725 case 0x35:
726 {
727 TCGv temp = tcg_temp_new_i32();
728 tcg_gen_movi_i32(cpu_pc, ctx->pc);
729 tcg_gen_movi_i32(temp, MOXIE_EX_BREAK);
730 gen_helper_raise_exception(cpu_env, temp);
731 tcg_temp_free_i32(temp);
732 }
733 break;
734 case 0x36:
735 {
736 int a = (opcode >> 4) & 0xf;
737 int b = opcode & 0xf;
738
739 TCGv t1 = tcg_temp_new_i32();
740 TCGv t2 = tcg_temp_new_i32();
741 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
742 tcg_gen_qemu_ld8u(t2, t1, ctx->memidx);
743 tcg_gen_mov_i32(REG(a), t2);
744
745 tcg_temp_free_i32(t1);
746 tcg_temp_free_i32(t2);
747
748 length = 6;
749 }
750 break;
751 case 0x37:
752 {
753 int a = (opcode >> 4) & 0xf;
754 int b = opcode & 0xf;
755
756 TCGv t1 = tcg_temp_new_i32();
757 TCGv t2 = tcg_temp_new_i32();
758 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
759 tcg_gen_qemu_st8(REG(b), t1, ctx->memidx);
760
761 tcg_temp_free_i32(t1);
762 tcg_temp_free_i32(t2);
763
764 length = 6;
765 }
766 break;
767 case 0x38:
768 {
769 int a = (opcode >> 4) & 0xf;
770 int b = opcode & 0xf;
771
772 TCGv t1 = tcg_temp_new_i32();
773 TCGv t2 = tcg_temp_new_i32();
774 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
775 tcg_gen_qemu_ld16u(t2, t1, ctx->memidx);
776 tcg_gen_mov_i32(REG(a), t2);
777
778 tcg_temp_free_i32(t1);
779 tcg_temp_free_i32(t2);
780
781 length = 6;
782 }
783 break;
784 case 0x39:
785 {
786 int a = (opcode >> 4) & 0xf;
787 int b = opcode & 0xf;
788
789 TCGv t1 = tcg_temp_new_i32();
790 TCGv t2 = tcg_temp_new_i32();
791 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
792 tcg_gen_qemu_st16(REG(b), t1, ctx->memidx);
793 tcg_temp_free_i32(t1);
794 tcg_temp_free_i32(t2);
795
796 length = 6;
797 }
798 break;
799 default:
800 {
801 TCGv temp = tcg_temp_new_i32();
802 tcg_gen_movi_i32(cpu_pc, ctx->pc);
803 tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
804 gen_helper_raise_exception(cpu_env, temp);
805 tcg_temp_free_i32(temp);
806 }
807 break;
808 }
809 }
810
811 return length;
812}
813
814
815void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
816{
817 MoxieCPU *cpu = moxie_env_get_cpu(env);
818 CPUState *cs = CPU(cpu);
819 DisasContext ctx;
820 target_ulong pc_start;
821 int num_insns, max_insns;
822
823 pc_start = tb->pc;
824 ctx.pc = pc_start;
825 ctx.saved_pc = -1;
826 ctx.tb = tb;
827 ctx.memidx = 0;
828 ctx.singlestep_enabled = 0;
829 ctx.bstate = BS_NONE;
830 num_insns = 0;
831 max_insns = tb->cflags & CF_COUNT_MASK;
832 if (max_insns == 0) {
833 max_insns = CF_COUNT_MASK;
834 }
835 if (max_insns > TCG_MAX_INSNS) {
836 max_insns = TCG_MAX_INSNS;
837 }
838
839 gen_tb_start(tb);
840 do {
841 tcg_gen_insn_start(ctx.pc);
842 num_insns++;
843
844 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
845 tcg_gen_movi_i32(cpu_pc, ctx.pc);
846 gen_helper_debug(cpu_env);
847 ctx.bstate = BS_EXCP;
848
849
850
851
852 ctx.pc += 2;
853 goto done_generating;
854 }
855
856 ctx.opcode = cpu_lduw_code(env, ctx.pc);
857 ctx.pc += decode_opc(cpu, &ctx);
858
859 if (num_insns >= max_insns) {
860 break;
861 }
862 if (cs->singlestep_enabled) {
863 break;
864 }
865 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
866 break;
867 }
868 } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
869
870 if (cs->singlestep_enabled) {
871 tcg_gen_movi_tl(cpu_pc, ctx.pc);
872 gen_helper_debug(cpu_env);
873 } else {
874 switch (ctx.bstate) {
875 case BS_STOP:
876 case BS_NONE:
877 gen_goto_tb(env, &ctx, 0, ctx.pc);
878 break;
879 case BS_EXCP:
880 tcg_gen_exit_tb(0);
881 break;
882 case BS_BRANCH:
883 default:
884 break;
885 }
886 }
887 done_generating:
888 gen_tb_end(tb, num_insns);
889
890 tb->size = ctx.pc - pc_start;
891 tb->icount = num_insns;
892}
893
894void restore_state_to_opc(CPUMoxieState *env, TranslationBlock *tb,
895 target_ulong *data)
896{
897 env->pc = data[0];
898}
899