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