net: add checking device state before run command
[sdk/emulator/qemu.git] / target-moxie / translate.c
1 /*
2  *  Moxie emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2009, 2013 Anthony Green
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* For information on the Moxie architecture, see
21  *    http://moxielogic.org/wiki
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 /* This is the state at translation time.  */
37 typedef struct DisasContext {
38     struct TranslationBlock *tb;
39     target_ulong pc, saved_pc;
40     uint32_t opcode;
41     uint32_t fp_status;
42     /* Routine used to access memory */
43     int memidx;
44     int bstate;
45     target_ulong btarget;
46     int singlestep_enabled;
47 } DisasContext;
48
49 enum {
50     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
51                       * exception condition */
52     BS_STOP     = 1, /* We want to stop translation for any reason */
53     BS_BRANCH   = 2, /* We reached a branch condition     */
54     BS_EXCP     = 3, /* We reached an exception condition */
55 };
56
57 static TCGv cpu_pc;
58 static TCGv cpu_gregs[16];
59 static TCGv_env cpu_env;
60 static TCGv cc_a, cc_b;
61
62 #include "exec/gen-icount.h"
63
64 #define REG(x) (cpu_gregs[x])
65
66 /* Extract the signed 10-bit offset from a 16-bit branch
67    instruction.  */
68 static int extract_branch_offset(int opcode)
69 {
70   return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
71 }
72
73 void 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
94 void 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     tcg_ctx.tcg_env = cpu_env;
110     cpu_pc = tcg_global_mem_new_i32(cpu_env,
111                                     offsetof(CPUMoxieState, pc), "$pc");
112     for (i = 0; i < 16; i++)
113         cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
114                                               offsetof(CPUMoxieState, gregs[i]),
115                                               gregnames[i]);
116
117     cc_a = tcg_global_mem_new_i32(cpu_env,
118                                   offsetof(CPUMoxieState, cc_a), "cc_a");
119     cc_b = tcg_global_mem_new_i32(cpu_env,
120                                   offsetof(CPUMoxieState, cc_b), "cc_b");
121
122     done_init = 1;
123 }
124
125 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
126 {
127     if (unlikely(ctx->singlestep_enabled)) {
128         return false;
129     }
130
131 #ifndef CONFIG_USER_ONLY
132     return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
133 #else
134     return true;
135 #endif
136 }
137
138 static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
139                                int n, target_ulong dest)
140 {
141     if (use_goto_tb(ctx, dest)) {
142         tcg_gen_goto_tb(n);
143         tcg_gen_movi_i32(cpu_pc, dest);
144         tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
145     } else {
146         tcg_gen_movi_i32(cpu_pc, dest);
147         if (ctx->singlestep_enabled) {
148             gen_helper_debug(cpu_env);
149         }
150         tcg_gen_exit_tb(0);
151     }
152 }
153
154 static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
155 {
156     CPUMoxieState *env = &cpu->env;
157
158     /* Local cache for the instruction opcode.  */
159     int opcode;
160     /* Set the default instruction length.  */
161     int length = 2;
162
163     /* Examine the 16-bit opcode.  */
164     opcode = ctx->opcode;
165
166     /* Decode instruction.  */
167     if (opcode & (1 << 15)) {
168         if (opcode & (1 << 14)) {
169             /* This is a Form 3 instruction.  */
170             int inst = (opcode >> 10 & 0xf);
171
172 #define BRANCH(cond)                                                         \
173     do {                                                                     \
174         TCGLabel *l1 = gen_new_label();                                      \
175         tcg_gen_brcond_i32(cond, cc_a, cc_b, l1);                            \
176         gen_goto_tb(env, ctx, 1, ctx->pc+2);                                 \
177         gen_set_label(l1);                                                   \
178         gen_goto_tb(env, ctx, 0, extract_branch_offset(opcode) + ctx->pc+2); \
179         ctx->bstate = BS_BRANCH;                                             \
180     } while (0)
181
182             switch (inst) {
183             case 0x00: /* beq */
184                 BRANCH(TCG_COND_EQ);
185                 break;
186             case 0x01: /* bne */
187                 BRANCH(TCG_COND_NE);
188                 break;
189             case 0x02: /* blt */
190                 BRANCH(TCG_COND_LT);
191                 break;
192             case 0x03: /* bgt */
193                 BRANCH(TCG_COND_GT);
194                 break;
195             case 0x04: /* bltu */
196                 BRANCH(TCG_COND_LTU);
197                 break;
198             case 0x05: /* bgtu */
199                 BRANCH(TCG_COND_GTU);
200                 break;
201             case 0x06: /* bge */
202                 BRANCH(TCG_COND_GE);
203                 break;
204             case 0x07: /* ble */
205                 BRANCH(TCG_COND_LE);
206                 break;
207             case 0x08: /* bgeu */
208                 BRANCH(TCG_COND_GEU);
209                 break;
210             case 0x09: /* bleu */
211                 BRANCH(TCG_COND_LEU);
212                 break;
213             default:
214                 {
215                     TCGv temp = tcg_temp_new_i32();
216                     tcg_gen_movi_i32(cpu_pc, ctx->pc);
217                     tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
218                     gen_helper_raise_exception(cpu_env, temp);
219                     tcg_temp_free_i32(temp);
220                 }
221                 break;
222             }
223         } else {
224             /* This is a Form 2 instruction.  */
225             int inst = (opcode >> 12 & 0x3);
226             switch (inst) {
227             case 0x00: /* inc */
228                 {
229                     int a = (opcode >> 8) & 0xf;
230                     unsigned int v = (opcode & 0xff);
231                     tcg_gen_addi_i32(REG(a), REG(a), v);
232                 }
233                 break;
234             case 0x01: /* dec */
235                 {
236                     int a = (opcode >> 8) & 0xf;
237                     unsigned int v = (opcode & 0xff);
238                     tcg_gen_subi_i32(REG(a), REG(a), v);
239                 }
240                 break;
241             case 0x02: /* gsr */
242                 {
243                     int a = (opcode >> 8) & 0xf;
244                     unsigned v = (opcode & 0xff);
245                     tcg_gen_ld_i32(REG(a), cpu_env,
246                                    offsetof(CPUMoxieState, sregs[v]));
247                 }
248                 break;
249             case 0x03: /* ssr */
250                 {
251                     int a = (opcode >> 8) & 0xf;
252                     unsigned v = (opcode & 0xff);
253                     tcg_gen_st_i32(REG(a), cpu_env,
254                                    offsetof(CPUMoxieState, sregs[v]));
255                 }
256                 break;
257             default:
258                 {
259                     TCGv temp = tcg_temp_new_i32();
260                     tcg_gen_movi_i32(cpu_pc, ctx->pc);
261                     tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
262                     gen_helper_raise_exception(cpu_env, temp);
263                     tcg_temp_free_i32(temp);
264                 }
265                 break;
266             }
267         }
268     } else {
269         /* This is a Form 1 instruction.  */
270         int inst = opcode >> 8;
271         switch (inst) {
272         case 0x00: /* nop */
273             break;
274         case 0x01: /* ldi.l (immediate) */
275             {
276                 int reg = (opcode >> 4) & 0xf;
277                 int val = cpu_ldl_code(env, ctx->pc+2);
278                 tcg_gen_movi_i32(REG(reg), val);
279                 length = 6;
280             }
281             break;
282         case 0x02: /* mov (register-to-register) */
283             {
284                 int dest  = (opcode >> 4) & 0xf;
285                 int src = opcode & 0xf;
286                 tcg_gen_mov_i32(REG(dest), REG(src));
287             }
288             break;
289         case 0x03: /* jsra */
290             {
291                 TCGv t1 = tcg_temp_new_i32();
292                 TCGv t2 = tcg_temp_new_i32();
293
294                 tcg_gen_movi_i32(t1, ctx->pc + 6);
295
296                 /* Make space for the static chain and return address.  */
297                 tcg_gen_subi_i32(t2, REG(1), 8);
298                 tcg_gen_mov_i32(REG(1), t2);
299                 tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
300
301                 /* Push the current frame pointer.  */
302                 tcg_gen_subi_i32(t2, REG(1), 4);
303                 tcg_gen_mov_i32(REG(1), t2);
304                 tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
305
306                 /* Set the pc and $fp.  */
307                 tcg_gen_mov_i32(REG(0), REG(1));
308
309                 gen_goto_tb(env, ctx, 0, cpu_ldl_code(env, ctx->pc+2));
310
311                 tcg_temp_free_i32(t1);
312                 tcg_temp_free_i32(t2);
313
314                 ctx->bstate = BS_BRANCH;
315                 length = 6;
316             }
317             break;
318         case 0x04: /* ret */
319             {
320                 TCGv t1 = tcg_temp_new_i32();
321
322                 /* The new $sp is the old $fp.  */
323                 tcg_gen_mov_i32(REG(1), REG(0));
324
325                 /* Pop the frame pointer.  */
326                 tcg_gen_qemu_ld32u(REG(0), REG(1), ctx->memidx);
327                 tcg_gen_addi_i32(t1, REG(1), 4);
328                 tcg_gen_mov_i32(REG(1), t1);
329
330
331                 /* Pop the return address and skip over the static chain
332                    slot.  */
333                 tcg_gen_qemu_ld32u(cpu_pc, REG(1), ctx->memidx);
334                 tcg_gen_addi_i32(t1, REG(1), 8);
335                 tcg_gen_mov_i32(REG(1), t1);
336
337                 tcg_temp_free_i32(t1);
338
339                 /* Jump... */
340                 tcg_gen_exit_tb(0);
341
342                 ctx->bstate = BS_BRANCH;
343             }
344             break;
345         case 0x05: /* add.l */
346             {
347                 int a = (opcode >> 4) & 0xf;
348                 int b = opcode & 0xf;
349
350                 tcg_gen_add_i32(REG(a), REG(a), REG(b));
351             }
352             break;
353         case 0x06: /* push */
354             {
355                 int a = (opcode >> 4) & 0xf;
356                 int b = opcode & 0xf;
357
358                 TCGv t1 = tcg_temp_new_i32();
359                 tcg_gen_subi_i32(t1, REG(a), 4);
360                 tcg_gen_mov_i32(REG(a), t1);
361                 tcg_gen_qemu_st32(REG(b), REG(a), ctx->memidx);
362                 tcg_temp_free_i32(t1);
363             }
364             break;
365         case 0x07: /* pop */
366             {
367                 int a = (opcode >> 4) & 0xf;
368                 int b = opcode & 0xf;
369                 TCGv t1 = tcg_temp_new_i32();
370
371                 tcg_gen_qemu_ld32u(REG(b), REG(a), ctx->memidx);
372                 tcg_gen_addi_i32(t1, REG(a), 4);
373                 tcg_gen_mov_i32(REG(a), t1);
374                 tcg_temp_free_i32(t1);
375             }
376             break;
377         case 0x08: /* lda.l */
378             {
379                 int reg = (opcode >> 4) & 0xf;
380
381                 TCGv ptr = tcg_temp_new_i32();
382                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
383                 tcg_gen_qemu_ld32u(REG(reg), ptr, ctx->memidx);
384                 tcg_temp_free_i32(ptr);
385
386                 length = 6;
387             }
388             break;
389         case 0x09: /* sta.l */
390             {
391                 int val = (opcode >> 4) & 0xf;
392
393                 TCGv ptr = tcg_temp_new_i32();
394                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
395                 tcg_gen_qemu_st32(REG(val), ptr, ctx->memidx);
396                 tcg_temp_free_i32(ptr);
397
398                 length = 6;
399             }
400             break;
401         case 0x0a: /* ld.l (register indirect) */
402             {
403                 int src  = opcode & 0xf;
404                 int dest = (opcode >> 4) & 0xf;
405
406                 tcg_gen_qemu_ld32u(REG(dest), REG(src), ctx->memidx);
407             }
408             break;
409         case 0x0b: /* st.l */
410             {
411                 int dest = (opcode >> 4) & 0xf;
412                 int val  = opcode & 0xf;
413
414                 tcg_gen_qemu_st32(REG(val), REG(dest), ctx->memidx);
415             }
416             break;
417         case 0x0c: /* ldo.l */
418             {
419                 int a = (opcode >> 4) & 0xf;
420                 int b = opcode & 0xf;
421
422                 TCGv t1 = tcg_temp_new_i32();
423                 TCGv t2 = tcg_temp_new_i32();
424                 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
425                 tcg_gen_qemu_ld32u(t2, t1, ctx->memidx);
426                 tcg_gen_mov_i32(REG(a), t2);
427
428                 tcg_temp_free_i32(t1);
429                 tcg_temp_free_i32(t2);
430
431                 length = 6;
432             }
433             break;
434         case 0x0d: /* sto.l */
435             {
436                 int a = (opcode >> 4) & 0xf;
437                 int b = opcode & 0xf;
438
439                 TCGv t1 = tcg_temp_new_i32();
440                 TCGv t2 = tcg_temp_new_i32();
441                 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
442                 tcg_gen_qemu_st32(REG(b), t1, ctx->memidx);
443
444                 tcg_temp_free_i32(t1);
445                 tcg_temp_free_i32(t2);
446
447                 length = 6;
448             }
449             break;
450         case 0x0e: /* cmp */
451             {
452                 int a  = (opcode >> 4) & 0xf;
453                 int b  = opcode & 0xf;
454
455                 tcg_gen_mov_i32(cc_a, REG(a));
456                 tcg_gen_mov_i32(cc_b, REG(b));
457             }
458             break;
459         case 0x19: /* jsr */
460             {
461                 int fnreg = (opcode >> 4) & 0xf;
462
463                 /* Load the stack pointer into T0.  */
464                 TCGv t1 = tcg_temp_new_i32();
465                 TCGv t2 = tcg_temp_new_i32();
466
467                 tcg_gen_movi_i32(t1, ctx->pc+2);
468
469                 /* Make space for the static chain and return address.  */
470                 tcg_gen_subi_i32(t2, REG(1), 8);
471                 tcg_gen_mov_i32(REG(1), t2);
472                 tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
473
474                 /* Push the current frame pointer.  */
475                 tcg_gen_subi_i32(t2, REG(1), 4);
476                 tcg_gen_mov_i32(REG(1), t2);
477                 tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
478
479                 /* Set the pc and $fp.  */
480                 tcg_gen_mov_i32(REG(0), REG(1));
481                 tcg_gen_mov_i32(cpu_pc, REG(fnreg));
482                 tcg_temp_free_i32(t1);
483                 tcg_temp_free_i32(t2);
484                 tcg_gen_exit_tb(0);
485                 ctx->bstate = BS_BRANCH;
486             }
487             break;
488         case 0x1a: /* jmpa */
489             {
490                 tcg_gen_movi_i32(cpu_pc, cpu_ldl_code(env, ctx->pc+2));
491                 tcg_gen_exit_tb(0);
492                 ctx->bstate = BS_BRANCH;
493                 length = 6;
494             }
495             break;
496         case 0x1b: /* ldi.b (immediate) */
497             {
498                 int reg = (opcode >> 4) & 0xf;
499                 int val = cpu_ldl_code(env, ctx->pc+2);
500                 tcg_gen_movi_i32(REG(reg), val);
501                 length = 6;
502             }
503             break;
504         case 0x1c: /* ld.b (register indirect) */
505             {
506                 int src  = opcode & 0xf;
507                 int dest = (opcode >> 4) & 0xf;
508
509                 tcg_gen_qemu_ld8u(REG(dest), REG(src), ctx->memidx);
510             }
511             break;
512         case 0x1d: /* lda.b */
513             {
514                 int reg = (opcode >> 4) & 0xf;
515
516                 TCGv ptr = tcg_temp_new_i32();
517                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
518                 tcg_gen_qemu_ld8u(REG(reg), ptr, ctx->memidx);
519                 tcg_temp_free_i32(ptr);
520
521                 length = 6;
522             }
523             break;
524         case 0x1e: /* st.b */
525             {
526                 int dest = (opcode >> 4) & 0xf;
527                 int val  = opcode & 0xf;
528
529                 tcg_gen_qemu_st8(REG(val), REG(dest), ctx->memidx);
530             }
531             break;
532         case 0x1f: /* sta.b */
533             {
534                 int val = (opcode >> 4) & 0xf;
535
536                 TCGv ptr = tcg_temp_new_i32();
537                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
538                 tcg_gen_qemu_st8(REG(val), ptr, ctx->memidx);
539                 tcg_temp_free_i32(ptr);
540
541                 length = 6;
542             }
543             break;
544         case 0x20: /* ldi.s (immediate) */
545             {
546                 int reg = (opcode >> 4) & 0xf;
547                 int val = cpu_ldl_code(env, ctx->pc+2);
548                 tcg_gen_movi_i32(REG(reg), val);
549                 length = 6;
550             }
551             break;
552         case 0x21: /* ld.s (register indirect) */
553             {
554                 int src  = opcode & 0xf;
555                 int dest = (opcode >> 4) & 0xf;
556
557                 tcg_gen_qemu_ld16u(REG(dest), REG(src), ctx->memidx);
558             }
559             break;
560         case 0x22: /* lda.s */
561             {
562                 int reg = (opcode >> 4) & 0xf;
563
564                 TCGv ptr = tcg_temp_new_i32();
565                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
566                 tcg_gen_qemu_ld16u(REG(reg), ptr, ctx->memidx);
567                 tcg_temp_free_i32(ptr);
568
569                 length = 6;
570             }
571             break;
572         case 0x23: /* st.s */
573             {
574                 int dest = (opcode >> 4) & 0xf;
575                 int val  = opcode & 0xf;
576
577                 tcg_gen_qemu_st16(REG(val), REG(dest), ctx->memidx);
578             }
579             break;
580         case 0x24: /* sta.s */
581             {
582                 int val = (opcode >> 4) & 0xf;
583
584                 TCGv ptr = tcg_temp_new_i32();
585                 tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
586                 tcg_gen_qemu_st16(REG(val), ptr, ctx->memidx);
587                 tcg_temp_free_i32(ptr);
588
589                 length = 6;
590             }
591             break;
592         case 0x25: /* jmp */
593             {
594                 int reg = (opcode >> 4) & 0xf;
595                 tcg_gen_mov_i32(cpu_pc, REG(reg));
596                 tcg_gen_exit_tb(0);
597                 ctx->bstate = BS_BRANCH;
598             }
599             break;
600         case 0x26: /* and */
601             {
602                 int a = (opcode >> 4) & 0xf;
603                 int b = opcode & 0xf;
604
605                 tcg_gen_and_i32(REG(a), REG(a), REG(b));
606             }
607             break;
608         case 0x27: /* lshr */
609             {
610                 int a = (opcode >> 4) & 0xf;
611                 int b = opcode & 0xf;
612
613                 TCGv sv = tcg_temp_new_i32();
614                 tcg_gen_andi_i32(sv, REG(b), 0x1f);
615                 tcg_gen_shr_i32(REG(a), REG(a), sv);
616                 tcg_temp_free_i32(sv);
617             }
618             break;
619         case 0x28: /* ashl */
620             {
621                 int a = (opcode >> 4) & 0xf;
622                 int b = opcode & 0xf;
623
624                 TCGv sv = tcg_temp_new_i32();
625                 tcg_gen_andi_i32(sv, REG(b), 0x1f);
626                 tcg_gen_shl_i32(REG(a), REG(a), sv);
627                 tcg_temp_free_i32(sv);
628             }
629             break;
630         case 0x29: /* sub.l */
631             {
632                 int a = (opcode >> 4) & 0xf;
633                 int b = opcode & 0xf;
634
635                 tcg_gen_sub_i32(REG(a), REG(a), REG(b));
636             }
637             break;
638         case 0x2a: /* neg */
639             {
640                 int a = (opcode >> 4) & 0xf;
641                 int b = opcode & 0xf;
642
643                 tcg_gen_neg_i32(REG(a), REG(b));
644             }
645             break;
646         case 0x2b: /* or */
647             {
648                 int a = (opcode >> 4) & 0xf;
649                 int b = opcode & 0xf;
650
651                 tcg_gen_or_i32(REG(a), REG(a), REG(b));
652             }
653             break;
654         case 0x2c: /* not */
655             {
656                 int a = (opcode >> 4) & 0xf;
657                 int b = opcode & 0xf;
658
659                 tcg_gen_not_i32(REG(a), REG(b));
660             }
661             break;
662         case 0x2d: /* ashr */
663             {
664                 int a = (opcode >> 4) & 0xf;
665                 int b = opcode & 0xf;
666
667                 TCGv sv = tcg_temp_new_i32();
668                 tcg_gen_andi_i32(sv, REG(b), 0x1f);
669                 tcg_gen_sar_i32(REG(a), REG(a), sv);
670                 tcg_temp_free_i32(sv);
671             }
672             break;
673         case 0x2e: /* xor */
674             {
675                 int a = (opcode >> 4) & 0xf;
676                 int b = opcode & 0xf;
677
678                 tcg_gen_xor_i32(REG(a), REG(a), REG(b));
679             }
680             break;
681         case 0x2f: /* mul.l */
682             {
683                 int a = (opcode >> 4) & 0xf;
684                 int b = opcode & 0xf;
685
686                 tcg_gen_mul_i32(REG(a), REG(a), REG(b));
687             }
688             break;
689         case 0x30: /* swi */
690             {
691                 int val = cpu_ldl_code(env, ctx->pc+2);
692
693                 TCGv temp = tcg_temp_new_i32();
694                 tcg_gen_movi_i32(temp, val);
695                 tcg_gen_st_i32(temp, cpu_env,
696                                offsetof(CPUMoxieState, sregs[3]));
697                 tcg_gen_movi_i32(cpu_pc, ctx->pc);
698                 tcg_gen_movi_i32(temp, MOXIE_EX_SWI);
699                 gen_helper_raise_exception(cpu_env, temp);
700                 tcg_temp_free_i32(temp);
701
702                 length = 6;
703             }
704             break;
705         case 0x31: /* div.l */
706             {
707                 int a = (opcode >> 4) & 0xf;
708                 int b = opcode & 0xf;
709                 tcg_gen_movi_i32(cpu_pc, ctx->pc);
710                 gen_helper_div(REG(a), cpu_env, REG(a), REG(b));
711             }
712             break;
713         case 0x32: /* udiv.l */
714             {
715                 int a = (opcode >> 4) & 0xf;
716                 int b = opcode & 0xf;
717                 tcg_gen_movi_i32(cpu_pc, ctx->pc);
718                 gen_helper_udiv(REG(a), cpu_env, REG(a), REG(b));
719             }
720             break;
721         case 0x33: /* mod.l */
722             {
723                 int a = (opcode >> 4) & 0xf;
724                 int b = opcode & 0xf;
725                 tcg_gen_rem_i32(REG(a), REG(a), REG(b));
726             }
727             break;
728         case 0x34: /* umod.l */
729             {
730                 int a = (opcode >> 4) & 0xf;
731                 int b = opcode & 0xf;
732                 tcg_gen_remu_i32(REG(a), REG(a), REG(b));
733             }
734             break;
735         case 0x35: /* brk */
736             {
737                 TCGv temp = tcg_temp_new_i32();
738                 tcg_gen_movi_i32(cpu_pc, ctx->pc);
739                 tcg_gen_movi_i32(temp, MOXIE_EX_BREAK);
740                 gen_helper_raise_exception(cpu_env, temp);
741                 tcg_temp_free_i32(temp);
742             }
743             break;
744         case 0x36: /* ldo.b */
745             {
746                 int a = (opcode >> 4) & 0xf;
747                 int b = opcode & 0xf;
748
749                 TCGv t1 = tcg_temp_new_i32();
750                 TCGv t2 = tcg_temp_new_i32();
751                 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
752                 tcg_gen_qemu_ld8u(t2, t1, ctx->memidx);
753                 tcg_gen_mov_i32(REG(a), t2);
754
755                 tcg_temp_free_i32(t1);
756                 tcg_temp_free_i32(t2);
757
758                 length = 6;
759             }
760             break;
761         case 0x37: /* sto.b */
762             {
763                 int a = (opcode >> 4) & 0xf;
764                 int b = opcode & 0xf;
765
766                 TCGv t1 = tcg_temp_new_i32();
767                 TCGv t2 = tcg_temp_new_i32();
768                 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
769                 tcg_gen_qemu_st8(REG(b), t1, ctx->memidx);
770
771                 tcg_temp_free_i32(t1);
772                 tcg_temp_free_i32(t2);
773
774                 length = 6;
775             }
776             break;
777         case 0x38: /* ldo.s */
778             {
779                 int a = (opcode >> 4) & 0xf;
780                 int b = opcode & 0xf;
781
782                 TCGv t1 = tcg_temp_new_i32();
783                 TCGv t2 = tcg_temp_new_i32();
784                 tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
785                 tcg_gen_qemu_ld16u(t2, t1, ctx->memidx);
786                 tcg_gen_mov_i32(REG(a), t2);
787
788                 tcg_temp_free_i32(t1);
789                 tcg_temp_free_i32(t2);
790
791                 length = 6;
792             }
793             break;
794         case 0x39: /* sto.s */
795             {
796                 int a = (opcode >> 4) & 0xf;
797                 int b = opcode & 0xf;
798
799                 TCGv t1 = tcg_temp_new_i32();
800                 TCGv t2 = tcg_temp_new_i32();
801                 tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
802                 tcg_gen_qemu_st16(REG(b), t1, ctx->memidx);
803                 tcg_temp_free_i32(t1);
804                 tcg_temp_free_i32(t2);
805
806                 length = 6;
807             }
808             break;
809         default:
810             {
811                 TCGv temp = tcg_temp_new_i32();
812                 tcg_gen_movi_i32(cpu_pc, ctx->pc);
813                 tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
814                 gen_helper_raise_exception(cpu_env, temp);
815                 tcg_temp_free_i32(temp);
816              }
817             break;
818         }
819     }
820
821     return length;
822 }
823
824 /* generate intermediate code for basic block 'tb'.  */
825 void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
826 {
827     MoxieCPU *cpu = moxie_env_get_cpu(env);
828     CPUState *cs = CPU(cpu);
829     DisasContext ctx;
830     target_ulong pc_start;
831     int num_insns, max_insns;
832
833     pc_start = tb->pc;
834     ctx.pc = pc_start;
835     ctx.saved_pc = -1;
836     ctx.tb = tb;
837     ctx.memidx = 0;
838     ctx.singlestep_enabled = 0;
839     ctx.bstate = BS_NONE;
840     num_insns = 0;
841     max_insns = tb->cflags & CF_COUNT_MASK;
842     if (max_insns == 0) {
843         max_insns = CF_COUNT_MASK;
844     }
845     if (max_insns > TCG_MAX_INSNS) {
846         max_insns = TCG_MAX_INSNS;
847     }
848
849     gen_tb_start(tb);
850     do {
851         tcg_gen_insn_start(ctx.pc);
852         num_insns++;
853
854         if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
855             tcg_gen_movi_i32(cpu_pc, ctx.pc);
856             gen_helper_debug(cpu_env);
857             ctx.bstate = BS_EXCP;
858             /* The address covered by the breakpoint must be included in
859                [tb->pc, tb->pc + tb->size) in order to for it to be
860                properly cleared -- thus we increment the PC here so that
861                the logic setting tb->size below does the right thing.  */
862             ctx.pc += 2;
863             goto done_generating;
864         }
865
866         ctx.opcode = cpu_lduw_code(env, ctx.pc);
867         ctx.pc += decode_opc(cpu, &ctx);
868
869         if (num_insns >= max_insns) {
870             break;
871         }
872         if (cs->singlestep_enabled) {
873             break;
874         }
875         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
876             break;
877         }
878     } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
879
880     if (cs->singlestep_enabled) {
881         tcg_gen_movi_tl(cpu_pc, ctx.pc);
882         gen_helper_debug(cpu_env);
883     } else {
884         switch (ctx.bstate) {
885         case BS_STOP:
886         case BS_NONE:
887             gen_goto_tb(env, &ctx, 0, ctx.pc);
888             break;
889         case BS_EXCP:
890             tcg_gen_exit_tb(0);
891             break;
892         case BS_BRANCH:
893         default:
894             break;
895         }
896     }
897  done_generating:
898     gen_tb_end(tb, num_insns);
899
900     tb->size = ctx.pc - pc_start;
901     tb->icount = num_insns;
902 }
903
904 void restore_state_to_opc(CPUMoxieState *env, TranslationBlock *tb,
905                           target_ulong *data)
906 {
907     env->pc = data[0];
908 }