Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 2c0262af

History | View | Annotate | Download (25.2 kB)

1 2c0262af bellard
/*
2 2c0262af bellard
 *  ARM translation
3 2c0262af bellard
 * 
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 2c0262af bellard
 *
6 2c0262af bellard
 * This library is free software; you can redistribute it and/or
7 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
8 2c0262af bellard
 * License as published by the Free Software Foundation; either
9 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
10 2c0262af bellard
 *
11 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
12 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 2c0262af bellard
 * Lesser General Public License for more details.
15 2c0262af bellard
 *
16 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
17 2c0262af bellard
 * License along with this library; if not, write to the Free Software
18 2c0262af bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 2c0262af bellard
 */
20 2c0262af bellard
#include <stdarg.h>
21 2c0262af bellard
#include <stdlib.h>
22 2c0262af bellard
#include <stdio.h>
23 2c0262af bellard
#include <string.h>
24 2c0262af bellard
#include <inttypes.h>
25 2c0262af bellard
26 2c0262af bellard
#include "cpu.h"
27 2c0262af bellard
#include "exec-all.h"
28 2c0262af bellard
#include "disas.h"
29 2c0262af bellard
30 2c0262af bellard
/* internal defines */
31 2c0262af bellard
typedef struct DisasContext {
32 2c0262af bellard
    uint8_t *pc;
33 2c0262af bellard
    int is_jmp;
34 2c0262af bellard
    struct TranslationBlock *tb;
35 2c0262af bellard
} DisasContext;
36 2c0262af bellard
37 2c0262af bellard
#define DISAS_JUMP_NEXT 4
38 2c0262af bellard
39 2c0262af bellard
/* XXX: move that elsewhere */
40 2c0262af bellard
static uint16_t *gen_opc_ptr;
41 2c0262af bellard
static uint32_t *gen_opparam_ptr;
42 2c0262af bellard
extern FILE *logfile;
43 2c0262af bellard
extern int loglevel;
44 2c0262af bellard
45 2c0262af bellard
enum {
46 2c0262af bellard
#define DEF(s, n, copy_size) INDEX_op_ ## s,
47 2c0262af bellard
#include "opc.h"
48 2c0262af bellard
#undef DEF
49 2c0262af bellard
    NB_OPS,
50 2c0262af bellard
};
51 2c0262af bellard
52 2c0262af bellard
#include "gen-op.h"
53 2c0262af bellard
54 2c0262af bellard
typedef void (GenOpFunc)(void);
55 2c0262af bellard
typedef void (GenOpFunc1)(long);
56 2c0262af bellard
typedef void (GenOpFunc2)(long, long);
57 2c0262af bellard
typedef void (GenOpFunc3)(long, long, long);
58 2c0262af bellard
59 2c0262af bellard
static GenOpFunc2 *gen_test_cc[14] = {
60 2c0262af bellard
    gen_op_test_eq,
61 2c0262af bellard
    gen_op_test_ne,
62 2c0262af bellard
    gen_op_test_cs,
63 2c0262af bellard
    gen_op_test_cc,
64 2c0262af bellard
    gen_op_test_mi,
65 2c0262af bellard
    gen_op_test_pl,
66 2c0262af bellard
    gen_op_test_vs,
67 2c0262af bellard
    gen_op_test_vc,
68 2c0262af bellard
    gen_op_test_hi,
69 2c0262af bellard
    gen_op_test_ls,
70 2c0262af bellard
    gen_op_test_ge,
71 2c0262af bellard
    gen_op_test_lt,
72 2c0262af bellard
    gen_op_test_gt,
73 2c0262af bellard
    gen_op_test_le,
74 2c0262af bellard
};
75 2c0262af bellard
76 2c0262af bellard
const uint8_t table_logic_cc[16] = {
77 2c0262af bellard
    1, /* and */
78 2c0262af bellard
    1, /* xor */
79 2c0262af bellard
    0, /* sub */
80 2c0262af bellard
    0, /* rsb */
81 2c0262af bellard
    0, /* add */
82 2c0262af bellard
    0, /* adc */
83 2c0262af bellard
    0, /* sbc */
84 2c0262af bellard
    0, /* rsc */
85 2c0262af bellard
    1, /* andl */
86 2c0262af bellard
    1, /* xorl */
87 2c0262af bellard
    0, /* cmp */
88 2c0262af bellard
    0, /* cmn */
89 2c0262af bellard
    1, /* orr */
90 2c0262af bellard
    1, /* mov */
91 2c0262af bellard
    1, /* bic */
92 2c0262af bellard
    1, /* mvn */
93 2c0262af bellard
};
94 2c0262af bellard
    
95 2c0262af bellard
static GenOpFunc1 *gen_shift_T1_im[4] = {
96 2c0262af bellard
    gen_op_shll_T1_im,
97 2c0262af bellard
    gen_op_shrl_T1_im,
98 2c0262af bellard
    gen_op_sarl_T1_im,
99 2c0262af bellard
    gen_op_rorl_T1_im,
100 2c0262af bellard
};
101 2c0262af bellard
102 2c0262af bellard
static GenOpFunc1 *gen_shift_T2_im[4] = {
103 2c0262af bellard
    gen_op_shll_T2_im,
104 2c0262af bellard
    gen_op_shrl_T2_im,
105 2c0262af bellard
    gen_op_sarl_T2_im,
106 2c0262af bellard
    gen_op_rorl_T2_im,
107 2c0262af bellard
};
108 2c0262af bellard
109 2c0262af bellard
static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
110 2c0262af bellard
    gen_op_shll_T1_im_cc,
111 2c0262af bellard
    gen_op_shrl_T1_im_cc,
112 2c0262af bellard
    gen_op_sarl_T1_im_cc,
113 2c0262af bellard
    gen_op_rorl_T1_im_cc,
114 2c0262af bellard
};
115 2c0262af bellard
116 2c0262af bellard
static GenOpFunc *gen_shift_T1_T0[4] = {
117 2c0262af bellard
    gen_op_shll_T1_T0,
118 2c0262af bellard
    gen_op_shrl_T1_T0,
119 2c0262af bellard
    gen_op_sarl_T1_T0,
120 2c0262af bellard
    gen_op_rorl_T1_T0,
121 2c0262af bellard
};
122 2c0262af bellard
123 2c0262af bellard
static GenOpFunc *gen_shift_T1_T0_cc[4] = {
124 2c0262af bellard
    gen_op_shll_T1_T0_cc,
125 2c0262af bellard
    gen_op_shrl_T1_T0_cc,
126 2c0262af bellard
    gen_op_sarl_T1_T0_cc,
127 2c0262af bellard
    gen_op_rorl_T1_T0_cc,
128 2c0262af bellard
};
129 2c0262af bellard
130 2c0262af bellard
static GenOpFunc *gen_op_movl_TN_reg[3][16] = {
131 2c0262af bellard
    {
132 2c0262af bellard
        gen_op_movl_T0_r0,
133 2c0262af bellard
        gen_op_movl_T0_r1,
134 2c0262af bellard
        gen_op_movl_T0_r2,
135 2c0262af bellard
        gen_op_movl_T0_r3,
136 2c0262af bellard
        gen_op_movl_T0_r4,
137 2c0262af bellard
        gen_op_movl_T0_r5,
138 2c0262af bellard
        gen_op_movl_T0_r6,
139 2c0262af bellard
        gen_op_movl_T0_r7,
140 2c0262af bellard
        gen_op_movl_T0_r8,
141 2c0262af bellard
        gen_op_movl_T0_r9,
142 2c0262af bellard
        gen_op_movl_T0_r10,
143 2c0262af bellard
        gen_op_movl_T0_r11,
144 2c0262af bellard
        gen_op_movl_T0_r12,
145 2c0262af bellard
        gen_op_movl_T0_r13,
146 2c0262af bellard
        gen_op_movl_T0_r14,
147 2c0262af bellard
        gen_op_movl_T0_r15,
148 2c0262af bellard
    },
149 2c0262af bellard
    {
150 2c0262af bellard
        gen_op_movl_T1_r0,
151 2c0262af bellard
        gen_op_movl_T1_r1,
152 2c0262af bellard
        gen_op_movl_T1_r2,
153 2c0262af bellard
        gen_op_movl_T1_r3,
154 2c0262af bellard
        gen_op_movl_T1_r4,
155 2c0262af bellard
        gen_op_movl_T1_r5,
156 2c0262af bellard
        gen_op_movl_T1_r6,
157 2c0262af bellard
        gen_op_movl_T1_r7,
158 2c0262af bellard
        gen_op_movl_T1_r8,
159 2c0262af bellard
        gen_op_movl_T1_r9,
160 2c0262af bellard
        gen_op_movl_T1_r10,
161 2c0262af bellard
        gen_op_movl_T1_r11,
162 2c0262af bellard
        gen_op_movl_T1_r12,
163 2c0262af bellard
        gen_op_movl_T1_r13,
164 2c0262af bellard
        gen_op_movl_T1_r14,
165 2c0262af bellard
        gen_op_movl_T1_r15,
166 2c0262af bellard
    },
167 2c0262af bellard
    {
168 2c0262af bellard
        gen_op_movl_T2_r0,
169 2c0262af bellard
        gen_op_movl_T2_r1,
170 2c0262af bellard
        gen_op_movl_T2_r2,
171 2c0262af bellard
        gen_op_movl_T2_r3,
172 2c0262af bellard
        gen_op_movl_T2_r4,
173 2c0262af bellard
        gen_op_movl_T2_r5,
174 2c0262af bellard
        gen_op_movl_T2_r6,
175 2c0262af bellard
        gen_op_movl_T2_r7,
176 2c0262af bellard
        gen_op_movl_T2_r8,
177 2c0262af bellard
        gen_op_movl_T2_r9,
178 2c0262af bellard
        gen_op_movl_T2_r10,
179 2c0262af bellard
        gen_op_movl_T2_r11,
180 2c0262af bellard
        gen_op_movl_T2_r12,
181 2c0262af bellard
        gen_op_movl_T2_r13,
182 2c0262af bellard
        gen_op_movl_T2_r14,
183 2c0262af bellard
        gen_op_movl_T2_r15,
184 2c0262af bellard
    },
185 2c0262af bellard
};
186 2c0262af bellard
187 2c0262af bellard
static GenOpFunc *gen_op_movl_reg_TN[2][16] = {
188 2c0262af bellard
    {
189 2c0262af bellard
        gen_op_movl_r0_T0,
190 2c0262af bellard
        gen_op_movl_r1_T0,
191 2c0262af bellard
        gen_op_movl_r2_T0,
192 2c0262af bellard
        gen_op_movl_r3_T0,
193 2c0262af bellard
        gen_op_movl_r4_T0,
194 2c0262af bellard
        gen_op_movl_r5_T0,
195 2c0262af bellard
        gen_op_movl_r6_T0,
196 2c0262af bellard
        gen_op_movl_r7_T0,
197 2c0262af bellard
        gen_op_movl_r8_T0,
198 2c0262af bellard
        gen_op_movl_r9_T0,
199 2c0262af bellard
        gen_op_movl_r10_T0,
200 2c0262af bellard
        gen_op_movl_r11_T0,
201 2c0262af bellard
        gen_op_movl_r12_T0,
202 2c0262af bellard
        gen_op_movl_r13_T0,
203 2c0262af bellard
        gen_op_movl_r14_T0,
204 2c0262af bellard
        gen_op_movl_r15_T0,
205 2c0262af bellard
    },
206 2c0262af bellard
    {
207 2c0262af bellard
        gen_op_movl_r0_T1,
208 2c0262af bellard
        gen_op_movl_r1_T1,
209 2c0262af bellard
        gen_op_movl_r2_T1,
210 2c0262af bellard
        gen_op_movl_r3_T1,
211 2c0262af bellard
        gen_op_movl_r4_T1,
212 2c0262af bellard
        gen_op_movl_r5_T1,
213 2c0262af bellard
        gen_op_movl_r6_T1,
214 2c0262af bellard
        gen_op_movl_r7_T1,
215 2c0262af bellard
        gen_op_movl_r8_T1,
216 2c0262af bellard
        gen_op_movl_r9_T1,
217 2c0262af bellard
        gen_op_movl_r10_T1,
218 2c0262af bellard
        gen_op_movl_r11_T1,
219 2c0262af bellard
        gen_op_movl_r12_T1,
220 2c0262af bellard
        gen_op_movl_r13_T1,
221 2c0262af bellard
        gen_op_movl_r14_T1,
222 2c0262af bellard
        gen_op_movl_r15_T1,
223 2c0262af bellard
    },
224 2c0262af bellard
};
225 2c0262af bellard
226 2c0262af bellard
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
227 2c0262af bellard
    gen_op_movl_T0_im,
228 2c0262af bellard
    gen_op_movl_T1_im,
229 2c0262af bellard
    gen_op_movl_T2_im,
230 2c0262af bellard
};
231 2c0262af bellard
232 2c0262af bellard
static inline void gen_movl_TN_reg(DisasContext *s, int reg, int t)
233 2c0262af bellard
{
234 2c0262af bellard
    int val;
235 2c0262af bellard
236 2c0262af bellard
    if (reg == 15) {
237 2c0262af bellard
        /* normaly, since we updated PC, we need only to add 4 */
238 2c0262af bellard
        val = (long)s->pc + 4;
239 2c0262af bellard
        gen_op_movl_TN_im[t](val);
240 2c0262af bellard
    } else {
241 2c0262af bellard
        gen_op_movl_TN_reg[t][reg]();
242 2c0262af bellard
    }
243 2c0262af bellard
}
244 2c0262af bellard
245 2c0262af bellard
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
246 2c0262af bellard
{
247 2c0262af bellard
    gen_movl_TN_reg(s, reg, 0);
248 2c0262af bellard
}
249 2c0262af bellard
250 2c0262af bellard
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
251 2c0262af bellard
{
252 2c0262af bellard
    gen_movl_TN_reg(s, reg, 1);
253 2c0262af bellard
}
254 2c0262af bellard
255 2c0262af bellard
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
256 2c0262af bellard
{
257 2c0262af bellard
    gen_movl_TN_reg(s, reg, 2);
258 2c0262af bellard
}
259 2c0262af bellard
260 2c0262af bellard
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
261 2c0262af bellard
{
262 2c0262af bellard
    gen_op_movl_reg_TN[t][reg]();
263 2c0262af bellard
    if (reg == 15) {
264 2c0262af bellard
        s->is_jmp = DISAS_JUMP;
265 2c0262af bellard
    }
266 2c0262af bellard
}
267 2c0262af bellard
268 2c0262af bellard
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
269 2c0262af bellard
{
270 2c0262af bellard
    gen_movl_reg_TN(s, reg, 0);
271 2c0262af bellard
}
272 2c0262af bellard
273 2c0262af bellard
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
274 2c0262af bellard
{
275 2c0262af bellard
    gen_movl_reg_TN(s, reg, 1);
276 2c0262af bellard
}
277 2c0262af bellard
278 2c0262af bellard
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
279 2c0262af bellard
{
280 2c0262af bellard
    int val, rm, shift;
281 2c0262af bellard
282 2c0262af bellard
    if (!(insn & (1 << 25))) {
283 2c0262af bellard
        /* immediate */
284 2c0262af bellard
        val = insn & 0xfff;
285 2c0262af bellard
        if (!(insn & (1 << 23)))
286 2c0262af bellard
            val = -val;
287 2c0262af bellard
        gen_op_addl_T1_im(val);
288 2c0262af bellard
    } else {
289 2c0262af bellard
        /* shift/register */
290 2c0262af bellard
        rm = (insn) & 0xf;
291 2c0262af bellard
        shift = (insn >> 7) & 0x1f;
292 2c0262af bellard
        gen_movl_T2_reg(s, rm);
293 2c0262af bellard
        if (shift != 0) {
294 2c0262af bellard
            gen_shift_T2_im[(insn >> 5) & 3](shift);
295 2c0262af bellard
        }
296 2c0262af bellard
        if (!(insn & (1 << 23)))
297 2c0262af bellard
            gen_op_subl_T1_T2();
298 2c0262af bellard
        else
299 2c0262af bellard
            gen_op_addl_T1_T2();
300 2c0262af bellard
    }
301 2c0262af bellard
}
302 2c0262af bellard
303 2c0262af bellard
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn)
304 2c0262af bellard
{
305 2c0262af bellard
    int val, rm;
306 2c0262af bellard
    
307 2c0262af bellard
    if (insn & (1 << 22)) {
308 2c0262af bellard
        /* immediate */
309 2c0262af bellard
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
310 2c0262af bellard
        if (!(insn & (1 << 23)))
311 2c0262af bellard
            val = -val;
312 2c0262af bellard
        gen_op_addl_T1_im(val);
313 2c0262af bellard
    } else {
314 2c0262af bellard
        /* register */
315 2c0262af bellard
        rm = (insn) & 0xf;
316 2c0262af bellard
        gen_movl_T2_reg(s, rm);
317 2c0262af bellard
        if (!(insn & (1 << 23)))
318 2c0262af bellard
            gen_op_subl_T1_T2();
319 2c0262af bellard
        else
320 2c0262af bellard
            gen_op_addl_T1_T2();
321 2c0262af bellard
    }
322 2c0262af bellard
}
323 2c0262af bellard
324 2c0262af bellard
static void disas_arm_insn(DisasContext *s)
325 2c0262af bellard
{
326 2c0262af bellard
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
327 2c0262af bellard
    
328 2c0262af bellard
    insn = ldl(s->pc);
329 2c0262af bellard
    s->pc += 4;
330 2c0262af bellard
    
331 2c0262af bellard
    cond = insn >> 28;
332 2c0262af bellard
    if (cond == 0xf)
333 2c0262af bellard
        goto illegal_op;
334 2c0262af bellard
    if (cond != 0xe) {
335 2c0262af bellard
        /* if not always execute, we generate a conditional jump to
336 2c0262af bellard
           next instruction */
337 2c0262af bellard
        gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
338 2c0262af bellard
        s->is_jmp = DISAS_JUMP_NEXT;
339 2c0262af bellard
    }
340 2c0262af bellard
    if (((insn & 0x0e000000) == 0 &&
341 2c0262af bellard
         (insn & 0x00000090) != 0x90) ||
342 2c0262af bellard
        ((insn & 0x0e000000) == (1 << 25))) {
343 2c0262af bellard
        int set_cc, logic_cc, shiftop;
344 2c0262af bellard
        
345 2c0262af bellard
        op1 = (insn >> 21) & 0xf;
346 2c0262af bellard
        set_cc = (insn >> 20) & 1;
347 2c0262af bellard
        logic_cc = table_logic_cc[op1] & set_cc;
348 2c0262af bellard
349 2c0262af bellard
        /* data processing instruction */
350 2c0262af bellard
        if (insn & (1 << 25)) {
351 2c0262af bellard
            /* immediate operand */
352 2c0262af bellard
            val = insn & 0xff;
353 2c0262af bellard
            shift = ((insn >> 8) & 0xf) * 2;
354 2c0262af bellard
            if (shift)
355 2c0262af bellard
                val = (val >> shift) | (val << (32 - shift));
356 2c0262af bellard
            gen_op_movl_T1_im(val);
357 2c0262af bellard
            /* XXX: is CF modified ? */
358 2c0262af bellard
        } else {
359 2c0262af bellard
            /* register */
360 2c0262af bellard
            rm = (insn) & 0xf;
361 2c0262af bellard
            gen_movl_T1_reg(s, rm);
362 2c0262af bellard
            shiftop = (insn >> 5) & 3;
363 2c0262af bellard
            if (!(insn & (1 << 4))) {
364 2c0262af bellard
                shift = (insn >> 7) & 0x1f;
365 2c0262af bellard
                if (shift != 0) {
366 2c0262af bellard
                    if (logic_cc) {
367 2c0262af bellard
                        gen_shift_T1_im_cc[shiftop](shift);
368 2c0262af bellard
                    } else {
369 2c0262af bellard
                        gen_shift_T1_im[shiftop](shift);
370 2c0262af bellard
                    }
371 2c0262af bellard
                }
372 2c0262af bellard
            } else {
373 2c0262af bellard
                rs = (insn >> 8) & 0xf;
374 2c0262af bellard
                gen_movl_T0_reg(s, rs);
375 2c0262af bellard
                if (logic_cc) {
376 2c0262af bellard
                    gen_shift_T1_T0_cc[shiftop]();
377 2c0262af bellard
                } else {
378 2c0262af bellard
                    gen_shift_T1_T0[shiftop]();
379 2c0262af bellard
                }
380 2c0262af bellard
            }
381 2c0262af bellard
        }
382 2c0262af bellard
        if (op1 != 0x0f && op1 != 0x0d) {
383 2c0262af bellard
            rn = (insn >> 16) & 0xf;
384 2c0262af bellard
            gen_movl_T0_reg(s, rn);
385 2c0262af bellard
        }
386 2c0262af bellard
        rd = (insn >> 12) & 0xf;
387 2c0262af bellard
        switch(op1) {
388 2c0262af bellard
        case 0x00:
389 2c0262af bellard
            gen_op_andl_T0_T1();
390 2c0262af bellard
            gen_movl_reg_T0(s, rd);
391 2c0262af bellard
            if (logic_cc)
392 2c0262af bellard
                gen_op_logic_T0_cc();
393 2c0262af bellard
            break;
394 2c0262af bellard
        case 0x01:
395 2c0262af bellard
            gen_op_xorl_T0_T1();
396 2c0262af bellard
            gen_movl_reg_T0(s, rd);
397 2c0262af bellard
            if (logic_cc)
398 2c0262af bellard
                gen_op_logic_T0_cc();
399 2c0262af bellard
            break;
400 2c0262af bellard
        case 0x02:
401 2c0262af bellard
            if (set_cc)
402 2c0262af bellard
                gen_op_subl_T0_T1_cc();
403 2c0262af bellard
            else
404 2c0262af bellard
                gen_op_subl_T0_T1();
405 2c0262af bellard
            gen_movl_reg_T0(s, rd);
406 2c0262af bellard
            break;
407 2c0262af bellard
        case 0x03:
408 2c0262af bellard
            if (set_cc)
409 2c0262af bellard
                gen_op_rsbl_T0_T1_cc();
410 2c0262af bellard
            else
411 2c0262af bellard
                gen_op_rsbl_T0_T1();
412 2c0262af bellard
            gen_movl_reg_T0(s, rd);
413 2c0262af bellard
            break;
414 2c0262af bellard
        case 0x04:
415 2c0262af bellard
            if (set_cc)
416 2c0262af bellard
                gen_op_addl_T0_T1_cc();
417 2c0262af bellard
            else
418 2c0262af bellard
                gen_op_addl_T0_T1();
419 2c0262af bellard
            gen_movl_reg_T0(s, rd);
420 2c0262af bellard
            break;
421 2c0262af bellard
        case 0x05:
422 2c0262af bellard
            if (set_cc)
423 2c0262af bellard
                gen_op_adcl_T0_T1_cc();
424 2c0262af bellard
            else
425 2c0262af bellard
                gen_op_adcl_T0_T1();
426 2c0262af bellard
            gen_movl_reg_T0(s, rd);
427 2c0262af bellard
            break;
428 2c0262af bellard
        case 0x06:
429 2c0262af bellard
            if (set_cc)
430 2c0262af bellard
                gen_op_sbcl_T0_T1_cc();
431 2c0262af bellard
            else
432 2c0262af bellard
                gen_op_sbcl_T0_T1();
433 2c0262af bellard
            gen_movl_reg_T0(s, rd);
434 2c0262af bellard
            break;
435 2c0262af bellard
        case 0x07:
436 2c0262af bellard
            if (set_cc)
437 2c0262af bellard
                gen_op_rscl_T0_T1_cc();
438 2c0262af bellard
            else
439 2c0262af bellard
                gen_op_rscl_T0_T1();
440 2c0262af bellard
            gen_movl_reg_T0(s, rd);
441 2c0262af bellard
            break;
442 2c0262af bellard
        case 0x08:
443 2c0262af bellard
            if (set_cc) {
444 2c0262af bellard
                gen_op_andl_T0_T1();
445 2c0262af bellard
                gen_op_logic_T0_cc();
446 2c0262af bellard
            }
447 2c0262af bellard
            break;
448 2c0262af bellard
        case 0x09:
449 2c0262af bellard
            if (set_cc) {
450 2c0262af bellard
                gen_op_xorl_T0_T1();
451 2c0262af bellard
                gen_op_logic_T0_cc();
452 2c0262af bellard
            }
453 2c0262af bellard
            break;
454 2c0262af bellard
        case 0x0a:
455 2c0262af bellard
            if (set_cc) {
456 2c0262af bellard
                gen_op_subl_T0_T1_cc();
457 2c0262af bellard
            }
458 2c0262af bellard
            break;
459 2c0262af bellard
        case 0x0b:
460 2c0262af bellard
            if (set_cc) {
461 2c0262af bellard
                gen_op_addl_T0_T1_cc();
462 2c0262af bellard
            }
463 2c0262af bellard
            break;
464 2c0262af bellard
        case 0x0c:
465 2c0262af bellard
            gen_op_orl_T0_T1();
466 2c0262af bellard
            gen_movl_reg_T0(s, rd);
467 2c0262af bellard
            if (logic_cc)
468 2c0262af bellard
                gen_op_logic_T0_cc();
469 2c0262af bellard
            break;
470 2c0262af bellard
        case 0x0d:
471 2c0262af bellard
            gen_movl_reg_T1(s, rd);
472 2c0262af bellard
            if (logic_cc)
473 2c0262af bellard
                gen_op_logic_T1_cc();
474 2c0262af bellard
            break;
475 2c0262af bellard
        case 0x0e:
476 2c0262af bellard
            gen_op_bicl_T0_T1();
477 2c0262af bellard
            gen_movl_reg_T0(s, rd);
478 2c0262af bellard
            if (logic_cc)
479 2c0262af bellard
                gen_op_logic_T0_cc();
480 2c0262af bellard
            break;
481 2c0262af bellard
        default:
482 2c0262af bellard
        case 0x0f:
483 2c0262af bellard
            gen_op_notl_T1();
484 2c0262af bellard
            gen_movl_reg_T1(s, rd);
485 2c0262af bellard
            if (logic_cc)
486 2c0262af bellard
                gen_op_logic_T1_cc();
487 2c0262af bellard
            break;
488 2c0262af bellard
        }
489 2c0262af bellard
    } else {
490 2c0262af bellard
        /* other instructions */
491 2c0262af bellard
        op1 = (insn >> 24) & 0xf;
492 2c0262af bellard
        switch(op1) {
493 2c0262af bellard
        case 0x0:
494 2c0262af bellard
        case 0x1:
495 2c0262af bellard
            sh = (insn >> 5) & 3;
496 2c0262af bellard
            if (sh == 0) {
497 2c0262af bellard
                if (op1 == 0x0) {
498 2c0262af bellard
                    rd = (insn >> 16) & 0xf;
499 2c0262af bellard
                    rn = (insn >> 12) & 0xf;
500 2c0262af bellard
                    rs = (insn >> 8) & 0xf;
501 2c0262af bellard
                    rm = (insn) & 0xf;
502 2c0262af bellard
                    if (!(insn & (1 << 23))) {
503 2c0262af bellard
                        /* 32 bit mul */
504 2c0262af bellard
                        gen_movl_T0_reg(s, rs);
505 2c0262af bellard
                        gen_movl_T1_reg(s, rm);
506 2c0262af bellard
                        gen_op_mul_T0_T1();
507 2c0262af bellard
                        if (insn & (1 << 21)) {
508 2c0262af bellard
                            gen_movl_T1_reg(s, rn);
509 2c0262af bellard
                            gen_op_addl_T0_T1();
510 2c0262af bellard
                        }
511 2c0262af bellard
                        if (insn & (1 << 20)) 
512 2c0262af bellard
                            gen_op_logic_T0_cc();
513 2c0262af bellard
                        gen_movl_reg_T0(s, rd);
514 2c0262af bellard
                    } else {
515 2c0262af bellard
                        /* 64 bit mul */
516 2c0262af bellard
                        gen_movl_T0_reg(s, rs);
517 2c0262af bellard
                        gen_movl_T1_reg(s, rm);
518 2c0262af bellard
                        if (insn & (1 << 22)) 
519 2c0262af bellard
                            gen_op_mull_T0_T1();
520 2c0262af bellard
                        else
521 2c0262af bellard
                            gen_op_imull_T0_T1();
522 2c0262af bellard
                        if (insn & (1 << 21)) 
523 2c0262af bellard
                            gen_op_addq_T0_T1(rn, rd);
524 2c0262af bellard
                        if (insn & (1 << 20)) 
525 2c0262af bellard
                            gen_op_logicq_cc();
526 2c0262af bellard
                        gen_movl_reg_T0(s, rn);
527 2c0262af bellard
                        gen_movl_reg_T1(s, rd);
528 2c0262af bellard
                    }
529 2c0262af bellard
                } else {
530 2c0262af bellard
                    /* SWP instruction */
531 2c0262af bellard
                    rn = (insn >> 16) & 0xf;
532 2c0262af bellard
                    rd = (insn >> 12) & 0xf;
533 2c0262af bellard
                    rm = (insn) & 0xf;
534 2c0262af bellard
                    
535 2c0262af bellard
                    gen_movl_T0_reg(s, rm);
536 2c0262af bellard
                    gen_movl_T1_reg(s, rn);
537 2c0262af bellard
                    if (insn & (1 << 22)) {
538 2c0262af bellard
                        gen_op_swpb_T0_T1();
539 2c0262af bellard
                    } else {
540 2c0262af bellard
                        gen_op_swpl_T0_T1();
541 2c0262af bellard
                    }
542 2c0262af bellard
                    gen_movl_reg_T0(s, rd);
543 2c0262af bellard
                }
544 2c0262af bellard
            } else {
545 2c0262af bellard
                /* load/store half word */
546 2c0262af bellard
                rn = (insn >> 16) & 0xf;
547 2c0262af bellard
                rd = (insn >> 12) & 0xf;
548 2c0262af bellard
                gen_movl_T1_reg(s, rn);
549 2c0262af bellard
                if (insn & (1 << 25))
550 2c0262af bellard
                    gen_add_datah_offset(s, insn);
551 2c0262af bellard
                if (insn & (1 << 20)) {
552 2c0262af bellard
                    /* load */
553 2c0262af bellard
                    switch(sh) {
554 2c0262af bellard
                    case 1:
555 2c0262af bellard
                        gen_op_lduw_T0_T1();
556 2c0262af bellard
                        break;
557 2c0262af bellard
                    case 2:
558 2c0262af bellard
                        gen_op_ldsb_T0_T1();
559 2c0262af bellard
                        break;
560 2c0262af bellard
                    default:
561 2c0262af bellard
                    case 3:
562 2c0262af bellard
                        gen_op_ldsw_T0_T1();
563 2c0262af bellard
                        break;
564 2c0262af bellard
                    }
565 2c0262af bellard
                } else {
566 2c0262af bellard
                    /* store */
567 2c0262af bellard
                    gen_op_stw_T0_T1();
568 2c0262af bellard
                }
569 2c0262af bellard
                if (!(insn & (1 << 24))) {
570 2c0262af bellard
                    gen_add_datah_offset(s, insn);
571 2c0262af bellard
                    gen_movl_reg_T1(s, rn);
572 2c0262af bellard
                } else if (insn & (1 << 21)) {
573 2c0262af bellard
                    gen_movl_reg_T1(s, rn);
574 2c0262af bellard
                }
575 2c0262af bellard
            }
576 2c0262af bellard
            break;
577 2c0262af bellard
        case 0x4:
578 2c0262af bellard
        case 0x5:
579 2c0262af bellard
        case 0x6:
580 2c0262af bellard
        case 0x7:
581 2c0262af bellard
            /* load/store byte/word */
582 2c0262af bellard
            rn = (insn >> 16) & 0xf;
583 2c0262af bellard
            rd = (insn >> 12) & 0xf;
584 2c0262af bellard
            gen_movl_T1_reg(s, rn);
585 2c0262af bellard
            if (insn & (1 << 24))
586 2c0262af bellard
                gen_add_data_offset(s, insn);
587 2c0262af bellard
            if (insn & (1 << 20)) {
588 2c0262af bellard
                /* load */
589 2c0262af bellard
                if (insn & (1 << 22))
590 2c0262af bellard
                    gen_op_ldub_T0_T1();
591 2c0262af bellard
                else
592 2c0262af bellard
                    gen_op_ldl_T0_T1();
593 2c0262af bellard
                gen_movl_reg_T0(s, rd);
594 2c0262af bellard
            } else {
595 2c0262af bellard
                /* store */
596 2c0262af bellard
                gen_movl_T0_reg(s, rd);
597 2c0262af bellard
                if (insn & (1 << 22))
598 2c0262af bellard
                    gen_op_stb_T0_T1();
599 2c0262af bellard
                else
600 2c0262af bellard
                    gen_op_stl_T0_T1();
601 2c0262af bellard
            }
602 2c0262af bellard
            if (!(insn & (1 << 24))) {
603 2c0262af bellard
                gen_add_data_offset(s, insn);
604 2c0262af bellard
                gen_movl_reg_T1(s, rn);
605 2c0262af bellard
            } else if (insn & (1 << 21))
606 2c0262af bellard
                gen_movl_reg_T1(s, rn); {
607 2c0262af bellard
            }
608 2c0262af bellard
            break;
609 2c0262af bellard
        case 0x08:
610 2c0262af bellard
        case 0x09:
611 2c0262af bellard
            {
612 2c0262af bellard
                int j, n;
613 2c0262af bellard
                /* load/store multiple words */
614 2c0262af bellard
                /* XXX: store correct base if write back */
615 2c0262af bellard
                if (insn & (1 << 22))
616 2c0262af bellard
                    goto illegal_op; /* only usable in supervisor mode */
617 2c0262af bellard
                rn = (insn >> 16) & 0xf;
618 2c0262af bellard
                gen_movl_T1_reg(s, rn);
619 2c0262af bellard
                
620 2c0262af bellard
                /* compute total size */
621 2c0262af bellard
                n = 0;
622 2c0262af bellard
                for(i=0;i<16;i++) {
623 2c0262af bellard
                    if (insn & (1 << i))
624 2c0262af bellard
                        n++;
625 2c0262af bellard
                }
626 2c0262af bellard
                /* XXX: test invalid n == 0 case ? */
627 2c0262af bellard
                if (insn & (1 << 23)) {
628 2c0262af bellard
                    if (insn & (1 << 24)) {
629 2c0262af bellard
                        /* pre increment */
630 2c0262af bellard
                        gen_op_addl_T1_im(4);
631 2c0262af bellard
                    } else {
632 2c0262af bellard
                        /* post increment */
633 2c0262af bellard
                    }
634 2c0262af bellard
                } else {
635 2c0262af bellard
                    if (insn & (1 << 24)) {
636 2c0262af bellard
                        /* pre decrement */
637 2c0262af bellard
                        gen_op_addl_T1_im(-(n * 4));
638 2c0262af bellard
                    } else {
639 2c0262af bellard
                        /* post decrement */
640 2c0262af bellard
                        if (n != 1)
641 2c0262af bellard
                            gen_op_addl_T1_im(-((n - 1) * 4));
642 2c0262af bellard
                    }
643 2c0262af bellard
                }
644 2c0262af bellard
                j = 0;
645 2c0262af bellard
                for(i=0;i<16;i++) {
646 2c0262af bellard
                    if (insn & (1 << i)) {
647 2c0262af bellard
                        if (insn & (1 << 20)) {
648 2c0262af bellard
                            /* load */
649 2c0262af bellard
                            gen_op_ldl_T0_T1();
650 2c0262af bellard
                            gen_movl_reg_T0(s, i);
651 2c0262af bellard
                        } else {
652 2c0262af bellard
                            /* store */
653 2c0262af bellard
                            if (i == 15) {
654 2c0262af bellard
                                /* special case: r15 = PC + 12 */
655 2c0262af bellard
                                val = (long)s->pc + 8;
656 2c0262af bellard
                                gen_op_movl_TN_im[0](val);
657 2c0262af bellard
                            } else {
658 2c0262af bellard
                                gen_movl_T0_reg(s, i);
659 2c0262af bellard
                            }
660 2c0262af bellard
                            gen_op_stl_T0_T1();
661 2c0262af bellard
                        }
662 2c0262af bellard
                        j++;
663 2c0262af bellard
                        /* no need to add after the last transfer */
664 2c0262af bellard
                        if (j != n)
665 2c0262af bellard
                            gen_op_addl_T1_im(4);
666 2c0262af bellard
                    }
667 2c0262af bellard
                }
668 2c0262af bellard
                if (insn & (1 << 21)) {
669 2c0262af bellard
                    /* write back */
670 2c0262af bellard
                    if (insn & (1 << 23)) {
671 2c0262af bellard
                        if (insn & (1 << 24)) {
672 2c0262af bellard
                            /* pre increment */
673 2c0262af bellard
                        } else {
674 2c0262af bellard
                            /* post increment */
675 2c0262af bellard
                            gen_op_addl_T1_im(4);
676 2c0262af bellard
                        }
677 2c0262af bellard
                    } else {
678 2c0262af bellard
                        if (insn & (1 << 24)) {
679 2c0262af bellard
                            /* pre decrement */
680 2c0262af bellard
                            if (n != 1)
681 2c0262af bellard
                                gen_op_addl_T1_im(-((n - 1) * 4));
682 2c0262af bellard
                        } else {
683 2c0262af bellard
                            /* post decrement */
684 2c0262af bellard
                            gen_op_addl_T1_im(-(n * 4));
685 2c0262af bellard
                        }
686 2c0262af bellard
                    }
687 2c0262af bellard
                    gen_movl_reg_T1(s, rn);
688 2c0262af bellard
                }
689 2c0262af bellard
            }
690 2c0262af bellard
            break;
691 2c0262af bellard
        case 0xa:
692 2c0262af bellard
        case 0xb:
693 2c0262af bellard
            {
694 2c0262af bellard
                int offset;
695 2c0262af bellard
                
696 2c0262af bellard
                /* branch (and link) */
697 2c0262af bellard
                val = (int)s->pc;
698 2c0262af bellard
                if (insn & (1 << 24)) {
699 2c0262af bellard
                    gen_op_movl_T0_im(val);
700 2c0262af bellard
                    gen_op_movl_reg_TN[0][14]();
701 2c0262af bellard
                }
702 2c0262af bellard
                offset = (((int)insn << 8) >> 8);
703 2c0262af bellard
                val += (offset << 2) + 4;
704 2c0262af bellard
                gen_op_jmp((long)s->tb, val);
705 2c0262af bellard
                s->is_jmp = DISAS_TB_JUMP;
706 2c0262af bellard
            }
707 2c0262af bellard
            break;
708 2c0262af bellard
        case 0xf:
709 2c0262af bellard
            /* swi */
710 2c0262af bellard
            gen_op_movl_T0_im((long)s->pc);
711 2c0262af bellard
            gen_op_movl_reg_TN[0][15]();
712 2c0262af bellard
            gen_op_swi();
713 2c0262af bellard
            s->is_jmp = DISAS_JUMP;
714 2c0262af bellard
            break;
715 2c0262af bellard
        case 0xc:
716 2c0262af bellard
        case 0xd:
717 2c0262af bellard
            rd = (insn >> 12) & 0x7;
718 2c0262af bellard
            rn = (insn >> 16) & 0xf;
719 2c0262af bellard
            gen_movl_T1_reg(s, rn);
720 2c0262af bellard
            val = (insn) & 0xff;
721 2c0262af bellard
            if (!(insn & (1 << 23)))
722 2c0262af bellard
                val = -val;
723 2c0262af bellard
            switch((insn >> 8) & 0xf) {
724 2c0262af bellard
            case 0x1:
725 2c0262af bellard
                /* load/store */
726 2c0262af bellard
                if ((insn & (1 << 24)))
727 2c0262af bellard
                    gen_op_addl_T1_im(val);
728 2c0262af bellard
                /* XXX: do it */
729 2c0262af bellard
                if (!(insn & (1 << 24)))
730 2c0262af bellard
                    gen_op_addl_T1_im(val);
731 2c0262af bellard
                if (insn & (1 << 21))
732 2c0262af bellard
                    gen_movl_reg_T1(s, rn);
733 2c0262af bellard
                break;
734 2c0262af bellard
            case 0x2:
735 2c0262af bellard
                {
736 2c0262af bellard
                    int n, i;
737 2c0262af bellard
                    /* load store multiple */
738 2c0262af bellard
                    if ((insn & (1 << 24)))
739 2c0262af bellard
                        gen_op_addl_T1_im(val);
740 2c0262af bellard
                    switch(insn & 0x00408000) {
741 2c0262af bellard
                    case 0x00008000: n = 1; break;
742 2c0262af bellard
                    case 0x00400000: n = 2; break;
743 2c0262af bellard
                    case 0x00408000: n = 3; break;
744 2c0262af bellard
                    default: n = 4; break;
745 2c0262af bellard
                    }
746 2c0262af bellard
                    for(i = 0;i < n; i++) {
747 2c0262af bellard
                        /* XXX: do it */
748 2c0262af bellard
                    }
749 2c0262af bellard
                    if (!(insn & (1 << 24)))
750 2c0262af bellard
                        gen_op_addl_T1_im(val);
751 2c0262af bellard
                    if (insn & (1 << 21))
752 2c0262af bellard
                        gen_movl_reg_T1(s, rn);
753 2c0262af bellard
                }
754 2c0262af bellard
                break;
755 2c0262af bellard
            default:
756 2c0262af bellard
                goto illegal_op;
757 2c0262af bellard
            }
758 2c0262af bellard
            break;
759 2c0262af bellard
        case 0x0e:
760 2c0262af bellard
            /* float ops */
761 2c0262af bellard
            /* XXX: do it */
762 2c0262af bellard
            switch((insn >> 20) & 0xf) {
763 2c0262af bellard
            case 0x2: /* wfs */
764 2c0262af bellard
                break;
765 2c0262af bellard
            case 0x3: /* rfs */
766 2c0262af bellard
                break;
767 2c0262af bellard
            case 0x4: /* wfc */
768 2c0262af bellard
                break;
769 2c0262af bellard
            case 0x5: /* rfc */
770 2c0262af bellard
                break;
771 2c0262af bellard
            default:
772 2c0262af bellard
                goto illegal_op;
773 2c0262af bellard
            }
774 2c0262af bellard
            break;
775 2c0262af bellard
        default:
776 2c0262af bellard
        illegal_op:
777 2c0262af bellard
            gen_op_movl_T0_im((long)s->pc - 4);
778 2c0262af bellard
            gen_op_movl_reg_TN[0][15]();
779 2c0262af bellard
            gen_op_undef_insn();
780 2c0262af bellard
            s->is_jmp = DISAS_JUMP;
781 2c0262af bellard
            break;
782 2c0262af bellard
        }
783 2c0262af bellard
    }
784 2c0262af bellard
}
785 2c0262af bellard
786 2c0262af bellard
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
787 2c0262af bellard
   basic block 'tb'. If search_pc is TRUE, also generate PC
788 2c0262af bellard
   information for each intermediate instruction. */
789 2c0262af bellard
static inline int gen_intermediate_code_internal(CPUState *env, 
790 2c0262af bellard
                                                 TranslationBlock *tb, 
791 2c0262af bellard
                                                 int search_pc)
792 2c0262af bellard
{
793 2c0262af bellard
    DisasContext dc1, *dc = &dc1;
794 2c0262af bellard
    uint16_t *gen_opc_end;
795 2c0262af bellard
    int j, lj;
796 2c0262af bellard
    uint8_t *pc_start;
797 2c0262af bellard
    
798 2c0262af bellard
    /* generate intermediate code */
799 2c0262af bellard
    pc_start = (uint8_t *)tb->pc;
800 2c0262af bellard
       
801 2c0262af bellard
    dc->tb = tb;
802 2c0262af bellard
803 2c0262af bellard
    gen_opc_ptr = gen_opc_buf;
804 2c0262af bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
805 2c0262af bellard
    gen_opparam_ptr = gen_opparam_buf;
806 2c0262af bellard
807 2c0262af bellard
    dc->is_jmp = DISAS_NEXT;
808 2c0262af bellard
    dc->pc = pc_start;
809 2c0262af bellard
    lj = -1;
810 2c0262af bellard
    do {
811 2c0262af bellard
        if (search_pc) {
812 2c0262af bellard
            j = gen_opc_ptr - gen_opc_buf;
813 2c0262af bellard
            if (lj < j) {
814 2c0262af bellard
                lj++;
815 2c0262af bellard
                while (lj < j)
816 2c0262af bellard
                    gen_opc_instr_start[lj++] = 0;
817 2c0262af bellard
            }
818 2c0262af bellard
            gen_opc_pc[lj] = (uint32_t)dc->pc;
819 2c0262af bellard
            gen_opc_instr_start[lj] = 1;
820 2c0262af bellard
        }
821 2c0262af bellard
        disas_arm_insn(dc);
822 2c0262af bellard
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && 
823 2c0262af bellard
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
824 2c0262af bellard
    switch(dc->is_jmp) {
825 2c0262af bellard
    case DISAS_JUMP_NEXT:
826 2c0262af bellard
    case DISAS_NEXT:
827 2c0262af bellard
        gen_op_jmp((long)dc->tb, (long)dc->pc);
828 2c0262af bellard
        break;
829 2c0262af bellard
    default:
830 2c0262af bellard
    case DISAS_JUMP:
831 2c0262af bellard
        /* indicate that the hash table must be used to find the next TB */
832 2c0262af bellard
        gen_op_movl_T0_0();
833 2c0262af bellard
        gen_op_exit_tb();
834 2c0262af bellard
        break;
835 2c0262af bellard
    case DISAS_TB_JUMP:
836 2c0262af bellard
        /* nothing more to generate */
837 2c0262af bellard
        break;
838 2c0262af bellard
    }
839 2c0262af bellard
    *gen_opc_ptr = INDEX_op_end;
840 2c0262af bellard
841 2c0262af bellard
#ifdef DEBUG_DISAS
842 2c0262af bellard
    if (loglevel) {
843 2c0262af bellard
        fprintf(logfile, "----------------\n");
844 2c0262af bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
845 2c0262af bellard
        disas(logfile, pc_start, dc->pc - pc_start, 0, 0);
846 2c0262af bellard
        fprintf(logfile, "\n");
847 2c0262af bellard
848 2c0262af bellard
        fprintf(logfile, "OP:\n");
849 2c0262af bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
850 2c0262af bellard
        fprintf(logfile, "\n");
851 2c0262af bellard
    }
852 2c0262af bellard
#endif
853 2c0262af bellard
    if (!search_pc)
854 2c0262af bellard
        tb->size = dc->pc - pc_start;
855 2c0262af bellard
    return 0;
856 2c0262af bellard
}
857 2c0262af bellard
858 2c0262af bellard
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
859 2c0262af bellard
{
860 2c0262af bellard
    return gen_intermediate_code_internal(env, tb, 0);
861 2c0262af bellard
}
862 2c0262af bellard
863 2c0262af bellard
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
864 2c0262af bellard
{
865 2c0262af bellard
    return gen_intermediate_code_internal(env, tb, 1);
866 2c0262af bellard
}
867 2c0262af bellard
868 2c0262af bellard
CPUARMState *cpu_arm_init(void)
869 2c0262af bellard
{
870 2c0262af bellard
    CPUARMState *env;
871 2c0262af bellard
872 2c0262af bellard
    cpu_exec_init();
873 2c0262af bellard
874 2c0262af bellard
    env = malloc(sizeof(CPUARMState));
875 2c0262af bellard
    if (!env)
876 2c0262af bellard
        return NULL;
877 2c0262af bellard
    memset(env, 0, sizeof(CPUARMState));
878 2c0262af bellard
    return env;
879 2c0262af bellard
}
880 2c0262af bellard
881 2c0262af bellard
void cpu_arm_close(CPUARMState *env)
882 2c0262af bellard
{
883 2c0262af bellard
    free(env);
884 2c0262af bellard
}
885 2c0262af bellard
886 2c0262af bellard
void cpu_arm_dump_state(CPUARMState *env, FILE *f, int flags)
887 2c0262af bellard
{
888 2c0262af bellard
    int i;
889 2c0262af bellard
890 2c0262af bellard
    for(i=0;i<16;i++) {
891 2c0262af bellard
        fprintf(f, "R%02d=%08x", i, env->regs[i]);
892 2c0262af bellard
        if ((i % 4) == 3)
893 2c0262af bellard
            fprintf(f, "\n");
894 2c0262af bellard
        else
895 2c0262af bellard
            fprintf(f, " ");
896 2c0262af bellard
    }
897 2c0262af bellard
    fprintf(f, "PSR=%08x %c%c%c%c\n", 
898 2c0262af bellard
            env->cpsr, 
899 2c0262af bellard
            env->cpsr & (1 << 31) ? 'N' : '-',
900 2c0262af bellard
            env->cpsr & (1 << 30) ? 'Z' : '-',
901 2c0262af bellard
            env->cpsr & (1 << 29) ? 'C' : '-',
902 2c0262af bellard
            env->cpsr & (1 << 28) ? 'V' : '-');
903 2c0262af bellard
}