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