Revision 1da92db2
b/tcg/sparc/tcg-target.c | ||
---|---|---|
117 | 117 |
tcg_abort(); |
118 | 118 |
*(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value; |
119 | 119 |
break; |
120 |
case R_SPARC_WDISP19: |
|
121 |
value -= (long)code_ptr; |
|
122 |
value >>= 2; |
|
123 |
if (!check_fit_tl(value, 19)) |
|
124 |
tcg_abort(); |
|
125 |
*(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x7ffff) | value; |
|
126 |
break; |
|
120 | 127 |
default: |
121 | 128 |
tcg_abort(); |
122 | 129 |
} |
... | ... | |
185 | 192 |
#define INSN_ASI(x) ((x) << 5) |
186 | 193 |
|
187 | 194 |
#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff)) |
195 |
#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff) |
|
188 | 196 |
#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff) |
189 | 197 |
|
190 | 198 |
#define INSN_COND(x, a) (((x) << 25) | ((a) << 29)) |
... | ... | |
421 | 429 |
tcg_out_sethi(s, TCG_REG_G0, 0); |
422 | 430 |
} |
423 | 431 |
|
424 |
static void tcg_out_branch(TCGContext *s, int opc, int label_index) |
|
432 |
static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
|
|
425 | 433 |
{ |
426 | 434 |
int32_t val; |
427 | 435 |
TCGLabel *l = &s->labels[label_index]; |
... | ... | |
436 | 444 |
} |
437 | 445 |
} |
438 | 446 |
|
447 |
#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
|
448 |
static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index) |
|
449 |
{ |
|
450 |
int32_t val; |
|
451 |
TCGLabel *l = &s->labels[label_index]; |
|
452 |
|
|
453 |
if (l->has_value) { |
|
454 |
val = l->u.value - (tcg_target_long)s->code_ptr; |
|
455 |
tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | |
|
456 |
(0x5 << 19) | |
|
457 |
INSN_OFF19(l->u.value - (unsigned long)s->code_ptr))); |
|
458 |
} else { |
|
459 |
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0); |
|
460 |
tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | |
|
461 |
(0x5 << 19) | 0)); |
|
462 |
} |
|
463 |
} |
|
464 |
#endif |
|
465 |
|
|
439 | 466 |
static const uint8_t tcg_cond_to_bcond[10] = { |
440 | 467 |
[TCG_COND_EQ] = COND_E, |
441 | 468 |
[TCG_COND_NE] = COND_NE, |
... | ... | |
449 | 476 |
[TCG_COND_GTU] = COND_GU, |
450 | 477 |
}; |
451 | 478 |
|
452 |
static void tcg_out_brcond(TCGContext *s, int cond, |
|
453 |
TCGArg arg1, TCGArg arg2, int const_arg2, |
|
454 |
int label_index) |
|
479 |
static void tcg_out_brcond_i32(TCGContext *s, int cond,
|
|
480 |
TCGArg arg1, TCGArg arg2, int const_arg2,
|
|
481 |
int label_index)
|
|
455 | 482 |
{ |
456 | 483 |
if (const_arg2 && arg2 == 0) |
457 | 484 |
/* orcc %g0, r, %g0 */ |
... | ... | |
459 | 486 |
else |
460 | 487 |
/* subcc r1, r2, %g0 */ |
461 | 488 |
tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); |
462 |
tcg_out_branch(s, tcg_cond_to_bcond[cond], label_index); |
|
489 |
tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index);
|
|
463 | 490 |
tcg_out_nop(s); |
464 | 491 |
} |
465 | 492 |
|
493 |
#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) |
|
494 |
static void tcg_out_brcond_i64(TCGContext *s, int cond, |
|
495 |
TCGArg arg1, TCGArg arg2, int const_arg2, |
|
496 |
int label_index) |
|
497 |
{ |
|
498 |
if (const_arg2 && arg2 == 0) |
|
499 |
/* orcc %g0, r, %g0 */ |
|
500 |
tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC); |
|
501 |
else |
|
502 |
/* subcc r1, r2, %g0 */ |
|
503 |
tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC); |
|
504 |
tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index); |
|
505 |
tcg_out_nop(s); |
|
506 |
} |
|
507 |
#endif |
|
508 |
|
|
466 | 509 |
/* Generate global QEMU prologue and epilogue code */ |
467 | 510 |
void tcg_target_qemu_prologue(TCGContext *s) |
468 | 511 |
{ |
... | ... | |
559 | 602 |
tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC); |
560 | 603 |
|
561 | 604 |
/* will become: |
562 |
be label1 */ |
|
605 |
be label1 |
|
606 |
or |
|
607 |
be,pt %xcc label1 */ |
|
563 | 608 |
label1_ptr = (uint32_t *)s->code_ptr; |
564 | 609 |
tcg_out32(s, 0); |
565 | 610 |
|
... | ... | |
627 | 672 |
tcg_out_nop(s); |
628 | 673 |
|
629 | 674 |
/* label1: */ |
675 |
#if TARGET_LONG_BITS == 32 |
|
676 |
/* be label1 */ |
|
630 | 677 |
*label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) | |
631 | 678 |
INSN_OFF22((unsigned long)s->code_ptr - |
632 | 679 |
(unsigned long)label1_ptr)); |
680 |
#else |
|
681 |
/* be,pt %xcc label1 */ |
|
682 |
*label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) | |
|
683 |
(0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr - |
|
684 |
(unsigned long)label1_ptr)); |
|
685 |
#endif |
|
633 | 686 |
|
634 | 687 |
/* ld [arg1 + x], arg1 */ |
635 | 688 |
tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) - |
... | ... | |
761 | 814 |
tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC); |
762 | 815 |
|
763 | 816 |
/* will become: |
764 |
be label1 */ |
|
817 |
be label1 |
|
818 |
or |
|
819 |
be,pt %xcc label1 */ |
|
765 | 820 |
label1_ptr = (uint32_t *)s->code_ptr; |
766 | 821 |
tcg_out32(s, 0); |
767 | 822 |
|
... | ... | |
797 | 852 |
/* nop (delay slot) */ |
798 | 853 |
tcg_out_nop(s); |
799 | 854 |
|
800 |
/* label1: */ |
|
855 |
#if TARGET_LONG_BITS == 32 |
|
856 |
/* be label1 */ |
|
801 | 857 |
*label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) | |
802 | 858 |
INSN_OFF22((unsigned long)s->code_ptr - |
803 | 859 |
(unsigned long)label1_ptr)); |
860 |
#else |
|
861 |
/* be,pt %xcc label1 */ |
|
862 |
*label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) | |
|
863 |
(0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr - |
|
864 |
(unsigned long)label1_ptr)); |
|
865 |
#endif |
|
804 | 866 |
|
805 | 867 |
/* ld [arg1 + x], arg1 */ |
806 | 868 |
tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) - |
... | ... | |
917 | 979 |
break; |
918 | 980 |
case INDEX_op_jmp: |
919 | 981 |
case INDEX_op_br: |
920 |
tcg_out_branch(s, COND_A, args[0]); |
|
982 |
tcg_out_branch_i32(s, COND_A, args[0]);
|
|
921 | 983 |
tcg_out_nop(s); |
922 | 984 |
break; |
923 | 985 |
case INDEX_op_movi_i32: |
... | ... | |
1009 | 1071 |
#endif |
1010 | 1072 |
|
1011 | 1073 |
case INDEX_op_brcond_i32: |
1012 |
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], |
|
1013 |
args[3]); |
|
1074 |
tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
|
|
1075 |
args[3]);
|
|
1014 | 1076 |
break; |
1015 | 1077 |
|
1016 | 1078 |
case INDEX_op_qemu_ld8u: |
... | ... | |
1074 | 1136 |
goto gen_arith32; |
1075 | 1137 |
|
1076 | 1138 |
case INDEX_op_brcond_i64: |
1077 |
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], |
|
1078 |
args[3]); |
|
1139 |
tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
|
|
1140 |
args[3]);
|
|
1079 | 1141 |
break; |
1080 | 1142 |
case INDEX_op_qemu_ld64: |
1081 | 1143 |
tcg_out_qemu_ld(s, args, 3); |
Also available in: Unified diff