Commit f5ef6aacd4043525c41bb37a02693011a168c14a
1 parent
21b20814
Implement qemu_ld/st, fix brcond, handle more corner cases
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4463 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
395 additions
and
29 deletions
tcg/sparc/tcg-target.c
... | ... | @@ -87,6 +87,12 @@ static const int tcg_target_call_oarg_regs[2] = { |
87 | 87 | TCG_REG_O1, |
88 | 88 | }; |
89 | 89 | |
90 | +static inline int check_fit(tcg_target_long val, unsigned int bits) | |
91 | +{ | |
92 | + return ((val << ((sizeof(tcg_target_long) * 8 - bits)) | |
93 | + >> (sizeof(tcg_target_long) * 8 - bits)) == val); | |
94 | +} | |
95 | + | |
90 | 96 | static void patch_reloc(uint8_t *code_ptr, int type, |
91 | 97 | tcg_target_long value, tcg_target_long addend) |
92 | 98 | { |
... | ... | @@ -97,6 +103,13 @@ static void patch_reloc(uint8_t *code_ptr, int type, |
97 | 103 | tcg_abort(); |
98 | 104 | *(uint32_t *)code_ptr = value; |
99 | 105 | break; |
106 | + case R_SPARC_WDISP22: | |
107 | + value -= (long)code_ptr; | |
108 | + value >>= 2; | |
109 | + if (!check_fit(value, 22)) | |
110 | + tcg_abort(); | |
111 | + *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value; | |
112 | + break; | |
100 | 113 | default: |
101 | 114 | tcg_abort(); |
102 | 115 | } |
... | ... | @@ -119,6 +132,8 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) |
119 | 132 | case 'L': /* qemu_ld/st constraint */ |
120 | 133 | ct->ct |= TCG_CT_REG; |
121 | 134 | tcg_regset_set32(ct->u.regs, 0, 0xffffffff); |
135 | + tcg_regset_reset_reg(ct->u.regs, TCG_REG_I0); | |
136 | + tcg_regset_reset_reg(ct->u.regs, TCG_REG_I1); | |
122 | 137 | break; |
123 | 138 | case 'I': |
124 | 139 | ct->ct |= TCG_CT_CONST_S11; |
... | ... | @@ -134,12 +149,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) |
134 | 149 | return 0; |
135 | 150 | } |
136 | 151 | |
137 | -static inline int check_fit(tcg_target_long val, unsigned int bits) | |
138 | -{ | |
139 | - return ((val << ((sizeof(tcg_target_long) * 8 - bits)) | |
140 | - >> (sizeof(tcg_target_long) * 8 - bits)) == val); | |
141 | -} | |
142 | - | |
143 | 152 | /* test if a constant matches the constraint */ |
144 | 153 | static inline int tcg_target_const_match(tcg_target_long val, |
145 | 154 | const TCGArgConstraint *arg_ct) |
... | ... | @@ -192,8 +201,8 @@ static inline int tcg_target_const_match(tcg_target_long val, |
192 | 201 | #define ARITH_ANDCC (INSN_OP(2) | INSN_OP3(0x11)) |
193 | 202 | #define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02)) |
194 | 203 | #define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03)) |
195 | -#define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x08)) | |
196 | -#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x18)) | |
204 | +#define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04)) | |
205 | +#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14)) | |
197 | 206 | #define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10)) |
198 | 207 | #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c)) |
199 | 208 | #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a)) |
... | ... | @@ -333,8 +342,10 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) |
333 | 342 | if (val != 0) { |
334 | 343 | if (check_fit(val, 13)) |
335 | 344 | tcg_out_arithi(s, reg, reg, val, ARITH_ADD); |
336 | - else | |
337 | - fprintf(stderr, "unimplemented addi %ld\n", (long)val); | |
345 | + else { | |
346 | + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val); | |
347 | + tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD); | |
348 | + } | |
338 | 349 | } |
339 | 350 | } |
340 | 351 | |
... | ... | @@ -350,10 +361,12 @@ static void tcg_out_branch(TCGContext *s, int opc, int label_index) |
350 | 361 | |
351 | 362 | if (l->has_value) { |
352 | 363 | val = l->u.value - (tcg_target_long)s->code_ptr; |
353 | - tcg_out32(s, (INSN_OP(0) | opc | INSN_OP2(0x2) | |
364 | + tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | |
354 | 365 | | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr))); |
355 | - } else | |
356 | - fprintf(stderr, "unimplemented branch\n"); | |
366 | + } else { | |
367 | + tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0); | |
368 | + tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0)); | |
369 | + } | |
357 | 370 | } |
358 | 371 | |
359 | 372 | static const uint8_t tcg_cond_to_bcond[10] = { |
... | ... | @@ -375,7 +388,7 @@ static void tcg_out_brcond(TCGContext *s, int cond, |
375 | 388 | { |
376 | 389 | if (const_arg2 && arg2 == 0) |
377 | 390 | /* andcc r, r, %g0 */ |
378 | - tcg_out_arithi(s, TCG_REG_G0, arg1, arg1, ARITH_ANDCC); | |
391 | + tcg_out_arith(s, TCG_REG_G0, arg1, arg1, ARITH_ANDCC); | |
379 | 392 | else |
380 | 393 | /* subcc r1, r2, %g0 */ |
381 | 394 | tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); |
... | ... | @@ -393,6 +406,359 @@ void tcg_target_qemu_prologue(TCGContext *s) |
393 | 406 | tcg_out_nop(s); |
394 | 407 | } |
395 | 408 | |
409 | +#if defined(CONFIG_SOFTMMU) | |
410 | +extern void __ldb_mmu(void); | |
411 | +extern void __ldw_mmu(void); | |
412 | +extern void __ldl_mmu(void); | |
413 | +extern void __ldq_mmu(void); | |
414 | + | |
415 | +extern void __stb_mmu(void); | |
416 | +extern void __stw_mmu(void); | |
417 | +extern void __stl_mmu(void); | |
418 | +extern void __stq_mmu(void); | |
419 | + | |
420 | + | |
421 | +static void *qemu_ld_helpers[4] = { | |
422 | + __ldb_mmu, | |
423 | + __ldw_mmu, | |
424 | + __ldl_mmu, | |
425 | + __ldq_mmu, | |
426 | +}; | |
427 | + | |
428 | +static void *qemu_st_helpers[4] = { | |
429 | + __stb_mmu, | |
430 | + __stw_mmu, | |
431 | + __stl_mmu, | |
432 | + __stq_mmu, | |
433 | +}; | |
434 | +#endif | |
435 | + | |
436 | +static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, | |
437 | + int opc) | |
438 | +{ | |
439 | + int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op; | |
440 | +#if defined(CONFIG_SOFTMMU) | |
441 | + uint8_t *label1_ptr, *label2_ptr; | |
442 | +#endif | |
443 | + | |
444 | + data_reg = *args++; | |
445 | + addr_reg = *args++; | |
446 | + mem_index = *args; | |
447 | + s_bits = opc & 3; | |
448 | + | |
449 | + r0 = TCG_REG_I0; | |
450 | + r1 = TCG_REG_I1; | |
451 | + | |
452 | +#if TARGET_LONG_BITS == 32 | |
453 | + ld_op = LDUW; | |
454 | +#else | |
455 | + ld_op = LDX; | |
456 | +#endif | |
457 | + | |
458 | +#if defined(CONFIG_SOFTMMU) | |
459 | + /* srl addr_reg, x, r1 */ | |
460 | + tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS, | |
461 | + SHIFT_SRL); | |
462 | + /* and addr_reg, x, r0 */ | |
463 | + tcg_out_arithi(s, r0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1), | |
464 | + ARITH_AND); | |
465 | + | |
466 | + /* and r1, x, r1 */ | |
467 | + tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, | |
468 | + ARITH_AND); | |
469 | + | |
470 | + /* add r1, x, r1 */ | |
471 | + tcg_out_arithi(s, r1, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_read), | |
472 | + ARITH_ADD); | |
473 | + | |
474 | + /* ld [env + r1], r1 */ | |
475 | + tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op); | |
476 | + | |
477 | + /* subcc r0, r1, %g0 */ | |
478 | + tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC); | |
479 | + | |
480 | + /* will become: | |
481 | + be label1 */ | |
482 | + label1_ptr = s->code_ptr; | |
483 | + tcg_out32(s, 0); | |
484 | + | |
485 | + /* mov (delay slot)*/ | |
486 | + tcg_out_mov(s, r0, addr_reg); | |
487 | + | |
488 | + /* XXX: move that code at the end of the TB */ | |
489 | + tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits] | |
490 | + - (tcg_target_ulong)s->code_ptr) >> 2) | |
491 | + & 0x3fffffff)); | |
492 | + /* mov (delay slot)*/ | |
493 | + tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index); | |
494 | + | |
495 | + switch(opc) { | |
496 | + case 0 | 4: | |
497 | + /* sll i0, 24/56, i0 */ | |
498 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, | |
499 | + sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL); | |
500 | + /* sra i0, 24/56, data_reg */ | |
501 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, | |
502 | + sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA); | |
503 | + break; | |
504 | + case 1 | 4: | |
505 | + /* sll i0, 16/48, i0 */ | |
506 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, | |
507 | + sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL); | |
508 | + /* sra i0, 16/48, data_reg */ | |
509 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, | |
510 | + sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA); | |
511 | + break; | |
512 | + case 2 | 4: | |
513 | + /* sll i0, 32, i0 */ | |
514 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL); | |
515 | + /* sra i0, 32, data_reg */ | |
516 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA); | |
517 | + break; | |
518 | + case 0: | |
519 | + case 1: | |
520 | + case 2: | |
521 | + case 3: | |
522 | + default: | |
523 | + /* mov */ | |
524 | + tcg_out_mov(s, data_reg, TCG_REG_I0); | |
525 | + break; | |
526 | + } | |
527 | + | |
528 | + /* will become: | |
529 | + ba label2 */ | |
530 | + label2_ptr = s->code_ptr; | |
531 | + tcg_out32(s, 0); | |
532 | + | |
533 | + /* label1: */ | |
534 | + *label1_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) | | |
535 | + INSN_OFF22((unsigned long)label1_ptr - | |
536 | + (unsigned long)s->code_ptr)); | |
537 | + | |
538 | + /* ld [r1 + x], r1 */ | |
539 | + tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) - | |
540 | + offsetof(CPUTLBEntry, addr_read), ld_op); | |
541 | + /* add x(r1), r0 */ | |
542 | + tcg_out_arith(s, r0, r1, r0, ARITH_ADD); | |
543 | +#else | |
544 | + r0 = addr_reg; | |
545 | +#endif | |
546 | + | |
547 | +#ifdef TARGET_WORDS_BIGENDIAN | |
548 | + bswap = 0; | |
549 | +#else | |
550 | + bswap = 1; | |
551 | +#endif | |
552 | + switch(opc) { | |
553 | + case 0: | |
554 | + /* ldub [r0], data_reg */ | |
555 | + tcg_out_ldst(s, data_reg, r0, 0, LDUB); | |
556 | + break; | |
557 | + case 0 | 4: | |
558 | + /* ldsb [r0], data_reg */ | |
559 | + tcg_out_ldst(s, data_reg, r0, 0, LDSB); | |
560 | + break; | |
561 | + case 1: | |
562 | + /* lduh [r0], data_reg */ | |
563 | + tcg_out_ldst(s, data_reg, r0, 0, LDUH); | |
564 | + if (bswap) { | |
565 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
566 | + } | |
567 | + break; | |
568 | + case 1 | 4: | |
569 | + /* ldsh [r0], data_reg */ | |
570 | + tcg_out_ldst(s, data_reg, r0, 0, LDSH); | |
571 | + if (bswap) { | |
572 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
573 | + } | |
574 | + break; | |
575 | + case 2: | |
576 | + /* lduw [r0], data_reg */ | |
577 | + tcg_out_ldst(s, data_reg, r0, 0, LDUW); | |
578 | + if (bswap) { | |
579 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
580 | + } | |
581 | + break; | |
582 | + case 2 | 4: | |
583 | + /* ldsw [r0], data_reg */ | |
584 | + tcg_out_ldst(s, data_reg, r0, 0, LDSW); | |
585 | + if (bswap) { | |
586 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
587 | + } | |
588 | + break; | |
589 | + case 3: | |
590 | + /* ldx [r0], data_reg */ | |
591 | + tcg_out_ldst(s, data_reg, r0, 0, LDX); | |
592 | + if (bswap) { | |
593 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
594 | + } | |
595 | + break; | |
596 | + default: | |
597 | + tcg_abort(); | |
598 | + } | |
599 | + | |
600 | +#if defined(CONFIG_SOFTMMU) | |
601 | + /* label2: */ | |
602 | + *label2_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) | | |
603 | + INSN_OFF22((unsigned long)label2_ptr - | |
604 | + (unsigned long)s->code_ptr)); | |
605 | +#endif | |
606 | +} | |
607 | + | |
608 | +static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, | |
609 | + int opc) | |
610 | +{ | |
611 | + int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op; | |
612 | +#if defined(CONFIG_SOFTMMU) | |
613 | + uint8_t *label1_ptr, *label2_ptr; | |
614 | +#endif | |
615 | + | |
616 | + data_reg = *args++; | |
617 | + addr_reg = *args++; | |
618 | + mem_index = *args; | |
619 | + | |
620 | + s_bits = opc; | |
621 | + | |
622 | + r0 = TCG_REG_I5; | |
623 | + r1 = TCG_REG_I4; | |
624 | + | |
625 | +#if TARGET_LONG_BITS == 32 | |
626 | + ld_op = LDUW; | |
627 | +#else | |
628 | + ld_op = LDX; | |
629 | +#endif | |
630 | + | |
631 | +#if defined(CONFIG_SOFTMMU) | |
632 | + /* srl addr_reg, x, r1 */ | |
633 | + tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS, | |
634 | + SHIFT_SRL); | |
635 | + /* and addr_reg, x, r0 */ | |
636 | + tcg_out_arithi(s, r0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1), | |
637 | + ARITH_AND); | |
638 | + | |
639 | + /* and r1, x, r1 */ | |
640 | + tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, | |
641 | + ARITH_AND); | |
642 | + | |
643 | + /* add r1, x, r1 */ | |
644 | + tcg_out_arithi(s, r1, r1, | |
645 | + offsetof(CPUState, tlb_table[mem_index][0].addr_write), | |
646 | + ARITH_ADD); | |
647 | + | |
648 | + /* ld [env + r1], r1 */ | |
649 | + tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op); | |
650 | + | |
651 | + /* subcc r0, r1, %g0 */ | |
652 | + tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC); | |
653 | + | |
654 | + /* will become: | |
655 | + be label1 */ | |
656 | + label1_ptr = s->code_ptr; | |
657 | + tcg_out32(s, 0); | |
658 | + /* mov (delay slot)*/ | |
659 | + tcg_out_mov(s, r0, addr_reg); | |
660 | + | |
661 | + switch(opc) { | |
662 | + case 0 | 4: | |
663 | + /* sll i0, 24/56, i0 */ | |
664 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, | |
665 | + sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL); | |
666 | + /* sra i0, 24/56, data_reg */ | |
667 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, | |
668 | + sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA); | |
669 | + break; | |
670 | + case 1 | 4: | |
671 | + /* sll i0, 16/48, i0 */ | |
672 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, | |
673 | + sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL); | |
674 | + /* sra i0, 16/48, data_reg */ | |
675 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, | |
676 | + sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA); | |
677 | + break; | |
678 | + case 2 | 4: | |
679 | + /* sll i0, 32, i0 */ | |
680 | + tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL); | |
681 | + /* sra i0, 32, data_reg */ | |
682 | + tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA); | |
683 | + break; | |
684 | + case 0: | |
685 | + case 1: | |
686 | + case 2: | |
687 | + case 3: | |
688 | + default: | |
689 | + /* mov */ | |
690 | + tcg_out_mov(s, data_reg, TCG_REG_I0); | |
691 | + break; | |
692 | + } | |
693 | + | |
694 | + tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits] | |
695 | + - (tcg_target_ulong)s->code_ptr) >> 2) | |
696 | + & 0x3fffffff)); | |
697 | + /* mov (delay slot)*/ | |
698 | + tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index); | |
699 | + | |
700 | + /* will become: | |
701 | + ba label2 */ | |
702 | + label2_ptr = s->code_ptr; | |
703 | + tcg_out32(s, 0); | |
704 | + | |
705 | + /* label1: */ | |
706 | + *label1_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) | | |
707 | + INSN_OFF22((unsigned long)label1_ptr - | |
708 | + (unsigned long)s->code_ptr)); | |
709 | + | |
710 | + /* ld [r1 + x], r1 */ | |
711 | + tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) - | |
712 | + offsetof(CPUTLBEntry, addr_write), ld_op); | |
713 | + /* add x(r1), r0 */ | |
714 | + tcg_out_arith(s, r0, r1, r0, ARITH_ADD); | |
715 | +#else | |
716 | + r0 = addr_reg; | |
717 | +#endif | |
718 | + | |
719 | +#ifdef TARGET_WORDS_BIGENDIAN | |
720 | + bswap = 0; | |
721 | +#else | |
722 | + bswap = 1; | |
723 | +#endif | |
724 | + switch(opc) { | |
725 | + case 0: | |
726 | + /* stb data_reg, [r0] */ | |
727 | + tcg_out_ldst(s, data_reg, r0, 0, STB); | |
728 | + break; | |
729 | + case 1: | |
730 | + if (bswap) { | |
731 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
732 | + } | |
733 | + /* sth data_reg, [r0] */ | |
734 | + tcg_out_ldst(s, data_reg, r0, 0, STH); | |
735 | + break; | |
736 | + case 2: | |
737 | + if (bswap) { | |
738 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
739 | + } | |
740 | + /* stw data_reg, [r0] */ | |
741 | + tcg_out_ldst(s, data_reg, r0, 0, STW); | |
742 | + break; | |
743 | + case 3: | |
744 | + if (bswap) { | |
745 | + fprintf(stderr, "unimplemented %s with bswap\n", __func__); | |
746 | + } | |
747 | + /* stx data_reg, [r0] */ | |
748 | + tcg_out_ldst(s, data_reg, r0, 0, STX); | |
749 | + break; | |
750 | + default: | |
751 | + tcg_abort(); | |
752 | + } | |
753 | + | |
754 | +#if defined(CONFIG_SOFTMMU) | |
755 | + /* label2: */ | |
756 | + *label2_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) | | |
757 | + INSN_OFF22((unsigned long)label2_ptr - | |
758 | + (unsigned long)s->code_ptr)); | |
759 | +#endif | |
760 | +} | |
761 | + | |
396 | 762 | static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
397 | 763 | const int *const_args) |
398 | 764 | { |
... | ... | @@ -437,10 +803,9 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
437 | 803 | } |
438 | 804 | break; |
439 | 805 | case INDEX_op_jmp: |
440 | - fprintf(stderr, "unimplemented jmp\n"); | |
441 | - break; | |
442 | 806 | case INDEX_op_br: |
443 | - fprintf(stderr, "unimplemented br\n"); | |
807 | + tcg_out_branch(s, COND_A, args[0]); | |
808 | + tcg_out_nop(s); | |
444 | 809 | break; |
445 | 810 | case INDEX_op_movi_i32: |
446 | 811 | tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]); |
... | ... | @@ -536,31 +901,31 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
536 | 901 | break; |
537 | 902 | |
538 | 903 | case INDEX_op_qemu_ld8u: |
539 | - fprintf(stderr, "unimplemented qld\n"); | |
904 | + tcg_out_qemu_ld(s, args, 0); | |
540 | 905 | break; |
541 | 906 | case INDEX_op_qemu_ld8s: |
542 | - fprintf(stderr, "unimplemented qld\n"); | |
907 | + tcg_out_qemu_ld(s, args, 0 | 4); | |
543 | 908 | break; |
544 | 909 | case INDEX_op_qemu_ld16u: |
545 | - fprintf(stderr, "unimplemented qld\n"); | |
910 | + tcg_out_qemu_ld(s, args, 1); | |
546 | 911 | break; |
547 | 912 | case INDEX_op_qemu_ld16s: |
548 | - fprintf(stderr, "unimplemented qld\n"); | |
913 | + tcg_out_qemu_ld(s, args, 1 | 4); | |
549 | 914 | break; |
550 | 915 | case INDEX_op_qemu_ld32u: |
551 | - fprintf(stderr, "unimplemented qld\n"); | |
916 | + tcg_out_qemu_ld(s, args, 2); | |
552 | 917 | break; |
553 | 918 | case INDEX_op_qemu_ld32s: |
554 | - fprintf(stderr, "unimplemented qld\n"); | |
919 | + tcg_out_qemu_ld(s, args, 2 | 4); | |
555 | 920 | break; |
556 | 921 | case INDEX_op_qemu_st8: |
557 | - fprintf(stderr, "unimplemented qst\n"); | |
922 | + tcg_out_qemu_st(s, args, 0); | |
558 | 923 | break; |
559 | 924 | case INDEX_op_qemu_st16: |
560 | - fprintf(stderr, "unimplemented qst\n"); | |
925 | + tcg_out_qemu_st(s, args, 1); | |
561 | 926 | break; |
562 | 927 | case INDEX_op_qemu_st32: |
563 | - fprintf(stderr, "unimplemented qst\n"); | |
928 | + tcg_out_qemu_st(s, args, 2); | |
564 | 929 | break; |
565 | 930 | |
566 | 931 | #if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
... | ... | @@ -596,13 +961,14 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
596 | 961 | goto gen_arith32; |
597 | 962 | |
598 | 963 | case INDEX_op_brcond_i64: |
599 | - fprintf(stderr, "unimplemented brcond\n"); | |
964 | + tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], | |
965 | + args[3]); | |
600 | 966 | break; |
601 | 967 | case INDEX_op_qemu_ld64: |
602 | - fprintf(stderr, "unimplemented qld\n"); | |
968 | + tcg_out_qemu_ld(s, args, 3); | |
603 | 969 | break; |
604 | 970 | case INDEX_op_qemu_st64: |
605 | - fprintf(stderr, "unimplemented qst\n"); | |
971 | + tcg_out_qemu_st(s, args, 3); | |
606 | 972 | break; |
607 | 973 | |
608 | 974 | #endif | ... | ... |