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