Statistics
| Branch: | Revision:

root / target-moxie / translate.c @ 3523e4bd

History | View | Annotate | Download (28.7 kB)

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