Statistics
| Branch: | Revision:

root / translate-arm.c @ 9da8ba18

History | View | Annotate | Download (25.2 kB)

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