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