These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / 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     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
124 static 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
144 static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
145 {
146     CPUMoxieState *env = &cpu->env;
147
148     /* Local cache for the instruction opcode.  */
149     int opcode;
150     /* Set the default instruction length.  */
151     int length = 2;
152
153     /* Examine the 16-bit opcode.  */
154     opcode = ctx->opcode;
155
156     /* Decode instruction.  */
157     if (opcode & (1 << 15)) {
158         if (opcode & (1 << 14)) {
159             /* This is a Form 3 instruction.  */
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: /* beq */
174                 BRANCH(TCG_COND_EQ);
175                 break;
176             case 0x01: /* bne */
177                 BRANCH(TCG_COND_NE);
178                 break;
179             case 0x02: /* blt */
180                 BRANCH(TCG_COND_LT);
181                 break;
182             case 0x03: /* bgt */
183                 BRANCH(TCG_COND_GT);
184                 break;
185             case 0x04: /* bltu */
186                 BRANCH(TCG_COND_LTU);
187                 break;
188             case 0x05: /* bgtu */
189                 BRANCH(TCG_COND_GTU);
190                 break;
191             case 0x06: /* bge */
192                 BRANCH(TCG_COND_GE);
193                 break;
194             case 0x07: /* ble */
195                 BRANCH(TCG_COND_LE);
196                 break;
197             case 0x08: /* bgeu */
198                 BRANCH(TCG_COND_GEU);
199                 break;
200             case 0x09: /* bleu */
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             /* This is a Form 2 instruction.  */
215             int inst = (opcode >> 12 & 0x3);
216             switch (inst) {
217             case 0x00: /* inc */
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: /* dec */
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: /* gsr */
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: /* ssr */
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         /* This is a Form 1 instruction.  */
260         int inst = opcode >> 8;
261         switch (inst) {
262         case 0x00: /* nop */
263             break;
264         case 0x01: /* ldi.l (immediate) */
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: /* mov (register-to-register) */
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: /* jsra */
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                 /* Make space for the static chain and return address.  */
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                 /* Push the current frame pointer.  */
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                 /* Set the pc and $fp.  */
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: /* ret */
309             {
310                 TCGv t1 = tcg_temp_new_i32();
311
312                 /* The new $sp is the old $fp.  */
313                 tcg_gen_mov_i32(REG(1), REG(0));
314
315                 /* Pop the frame pointer.  */
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                 /* Pop the return address and skip over the static chain
322                    slot.  */
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                 /* Jump... */
330                 tcg_gen_exit_tb(0);
331
332                 ctx->bstate = BS_BRANCH;
333             }
334             break;
335         case 0x05: /* add.l */
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: /* push */
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: /* pop */
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: /* lda.l */
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: /* sta.l */
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: /* ld.l (register indirect) */
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: /* st.l */
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: /* ldo.l */
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: /* sto.l */
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: /* cmp */
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: /* jsr */
450             {
451                 int fnreg = (opcode >> 4) & 0xf;
452
453                 /* Load the stack pointer into T0.  */
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                 /* Make space for the static chain and return address.  */
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                 /* Push the current frame pointer.  */
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                 /* Set the pc and $fp.  */
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: /* jmpa */
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: /* ldi.b (immediate) */
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: /* ld.b (register indirect) */
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: /* lda.b */
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: /* st.b */
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: /* sta.b */
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: /* ldi.s (immediate) */
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: /* ld.s (register indirect) */
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: /* lda.s */
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: /* st.s */
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: /* sta.s */
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: /* jmp */
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: /* and */
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: /* lshr */
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: /* ashl */
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: /* sub.l */
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: /* neg */
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: /* or */
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: /* not */
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: /* ashr */
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: /* xor */
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: /* mul.l */
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: /* swi */
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: /* div.l */
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: /* udiv.l */
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: /* mod.l */
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: /* umod.l */
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: /* brk */
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: /* ldo.b */
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: /* sto.b */
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: /* ldo.s */
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: /* sto.s */
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 /* generate intermediate code for basic block 'tb'.  */
815 void 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             /* The address covered by the breakpoint must be included in
849                [tb->pc, tb->pc + tb->size) in order to for it to be
850                properly cleared -- thus we increment the PC here so that
851                the logic setting tb->size below does the right thing.  */
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
894 void restore_state_to_opc(CPUMoxieState *env, TranslationBlock *tb,
895                           target_ulong *data)
896 {
897     env->pc = data[0];
898 }