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