mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 08:51:06 +00:00
tcg: Change generator-side labels to a pointer
This is less about improved type checking than enabling a subsequent change to the representation of labels. Backports commit bec1631100323fac0900aea71043d5c4e22fc2fa from qemu
This commit is contained in:
parent
232632e76c
commit
00b0a50f47
|
@ -837,12 +837,10 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
|
||||||
flush_icache_range(jmp_addr, jmp_addr + 4);
|
flush_icache_range(jmp_addr, jmp_addr + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tcg_out_goto_label(TCGContext *s, int label_index)
|
static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label_index];
|
|
||||||
|
|
||||||
if (!l->has_value) {
|
if (!l->has_value) {
|
||||||
tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, label_index, 0);
|
tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, l, 0);
|
||||||
tcg_out_goto_noaddr(s);
|
tcg_out_goto_noaddr(s);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_goto(s, l->u.value_ptr);
|
tcg_out_goto(s, l->u.value_ptr);
|
||||||
|
@ -850,9 +848,8 @@ static inline void tcg_out_goto_label(TCGContext *s, int label_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
|
static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
|
||||||
TCGArg b, bool b_const, int label)
|
TCGArg b, bool b_const, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label];
|
|
||||||
intptr_t offset;
|
intptr_t offset;
|
||||||
bool need_cmp;
|
bool need_cmp;
|
||||||
|
|
||||||
|
@ -864,7 +861,7 @@ static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!l->has_value) {
|
if (!l->has_value) {
|
||||||
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, label, 0);
|
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
|
||||||
offset = tcg_in32(s) >> 5;
|
offset = tcg_in32(s) >> 5;
|
||||||
} else {
|
} else {
|
||||||
offset = l->u.value_ptr - s->code_ptr;
|
offset = l->u.value_ptr - s->code_ptr;
|
||||||
|
@ -1272,7 +1269,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tcg_out_goto_label(s, a0);
|
tcg_out_goto_label(s, arg_label(s, a0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_ld8u_i32:
|
case INDEX_op_ld8u_i32:
|
||||||
|
@ -1495,7 +1492,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
a1 = (int32_t)a1;
|
a1 = (int32_t)a1;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], args[3]);
|
tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
|
|
|
@ -1038,14 +1038,12 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
|
static inline void tcg_out_goto_label(TCGContext *s, int cond, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label_index];
|
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
tcg_out_goto(s, cond, l->u.value_ptr);
|
tcg_out_goto(s, cond, l->u.value_ptr);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 0);
|
tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, l, 0);
|
||||||
tcg_out_b_noaddr(s, cond);
|
tcg_out_b_noaddr(s, cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1657,7 +1655,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
s->tb_next_offset[args[0]] = tcg_current_code_size(s);
|
s->tb_next_offset[args[0]] = tcg_current_code_size(s);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tcg_out_goto_label(s, COND_AL, args[0]);
|
tcg_out_goto_label(s, COND_AL, arg_label(s, args[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_ld8u_i32:
|
case INDEX_op_ld8u_i32:
|
||||||
|
@ -1821,7 +1819,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
|
tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
|
||||||
args[0], args[1], const_args[1]);
|
args[0], args[1], const_args[1]);
|
||||||
tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
|
tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]],
|
||||||
|
arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_brcond2_i32:
|
case INDEX_op_brcond2_i32:
|
||||||
/* The resulting conditions are:
|
/* The resulting conditions are:
|
||||||
|
@ -1836,7 +1835,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
args[1], args[3], const_args[3]);
|
args[1], args[3], const_args[3]);
|
||||||
tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
|
tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
|
||||||
args[0], args[2], const_args[2]);
|
args[0], args[2], const_args[2]);
|
||||||
tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
|
tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]],
|
||||||
|
arg_label(s, args[5]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
|
tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
|
||||||
|
|
|
@ -879,10 +879,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use SMALL != 0 to force a short forward branch. */
|
/* Use SMALL != 0 to force a short forward branch. */
|
||||||
static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int smallflag)
|
static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int smallflag)
|
||||||
{
|
{
|
||||||
int32_t val, val1;
|
int32_t val, val1;
|
||||||
TCGLabel *l = &s->labels[label_index];
|
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
val = tcg_pcrel_diff(s, l->u.value_ptr);
|
val = tcg_pcrel_diff(s, l->u.value_ptr);
|
||||||
|
@ -912,7 +911,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int smallflag)
|
||||||
} else {
|
} else {
|
||||||
tcg_out8(s, OPC_JCC_short + opc);
|
tcg_out8(s, OPC_JCC_short + opc);
|
||||||
}
|
}
|
||||||
tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
|
tcg_out_reloc(s, s->code_ptr, R_386_PC8, l, -1);
|
||||||
s->code_ptr += 1;
|
s->code_ptr += 1;
|
||||||
} else {
|
} else {
|
||||||
if (opc == -1) {
|
if (opc == -1) {
|
||||||
|
@ -920,7 +919,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int smallflag)
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
|
tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
|
||||||
}
|
}
|
||||||
tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
|
tcg_out_reloc(s, s->code_ptr, R_386_PC32, l, -4);
|
||||||
s->code_ptr += 4;
|
s->code_ptr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,19 +941,19 @@ static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
|
||||||
|
|
||||||
static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
|
static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
|
||||||
TCGArg arg1, TCGArg arg2, int const_arg2,
|
TCGArg arg1, TCGArg arg2, int const_arg2,
|
||||||
int label_index, int smallflag)
|
TCGLabel *label, int smallflag)
|
||||||
{
|
{
|
||||||
tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
|
tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
|
||||||
tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, smallflag);
|
tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, smallflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 64
|
#if TCG_TARGET_REG_BITS == 64
|
||||||
static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
|
static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
|
||||||
TCGArg arg1, TCGArg arg2, int const_arg2,
|
TCGArg arg1, TCGArg arg2, int const_arg2,
|
||||||
int label_index, int smallflag)
|
TCGLabel *label, int smallflag)
|
||||||
{
|
{
|
||||||
tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
|
tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
|
||||||
tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, smallflag);
|
tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, smallflag);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* XXX: we implement it at the target level to avoid having to
|
/* XXX: we implement it at the target level to avoid having to
|
||||||
|
@ -962,76 +961,77 @@ static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
|
||||||
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
|
||||||
const int *const_args, int smallflag)
|
const int *const_args, int smallflag)
|
||||||
{
|
{
|
||||||
int label_next = label_arg(s, gen_new_label(s));
|
TCGLabel *label_next = gen_new_label(s);
|
||||||
|
TCGLabel *label_this = arg_label(s, args[5]);
|
||||||
|
|
||||||
switch(args[4]) {
|
switch(args[4]) {
|
||||||
case TCG_COND_EQ:
|
case TCG_COND_EQ:
|
||||||
tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
|
||||||
label_next, 1);
|
label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_NE:
|
case TCG_COND_NE:
|
||||||
tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_LT:
|
case TCG_COND_LT:
|
||||||
tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_LE:
|
case TCG_COND_LE:
|
||||||
tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_GT:
|
case TCG_COND_GT:
|
||||||
tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_GE:
|
case TCG_COND_GE:
|
||||||
tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_LTU:
|
case TCG_COND_LTU:
|
||||||
tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_LEU:
|
case TCG_COND_LEU:
|
||||||
tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_GTU:
|
case TCG_COND_GTU:
|
||||||
tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
case TCG_COND_GEU:
|
case TCG_COND_GEU:
|
||||||
tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
|
tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
tcg_out_jxx(s, JCC_JNE, label_next, 1);
|
||||||
tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
|
tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
|
||||||
args[5], smallflag);
|
label_this, smallflag);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tcg_abort();
|
tcg_abort();
|
||||||
|
@ -1061,7 +1061,7 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||||
const int *const_args)
|
const int *const_args)
|
||||||
{
|
{
|
||||||
TCGArg new_args[6];
|
TCGArg new_args[6];
|
||||||
int label_true, label_over;
|
TCGLabel *label_true, *label_over;
|
||||||
|
|
||||||
memcpy(new_args, args+1, 5*sizeof(TCGArg));
|
memcpy(new_args, args+1, 5*sizeof(TCGArg));
|
||||||
|
|
||||||
|
@ -1070,10 +1070,10 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||||
|| (!const_args[4] && args[0] == args[4])) {
|
|| (!const_args[4] && args[0] == args[4])) {
|
||||||
/* When the destination overlaps with one of the argument
|
/* When the destination overlaps with one of the argument
|
||||||
registers, don't do anything tricky. */
|
registers, don't do anything tricky. */
|
||||||
label_true = label_arg(s, gen_new_label(s));
|
label_true = gen_new_label(s);
|
||||||
label_over = label_arg(s, gen_new_label(s));
|
label_over = gen_new_label(s);
|
||||||
|
|
||||||
new_args[5] = label_true;
|
new_args[5] = label_arg(s, label_true);
|
||||||
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
||||||
|
|
||||||
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
||||||
|
@ -1089,9 +1089,9 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||||
|
|
||||||
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
|
||||||
|
|
||||||
label_over = label_arg(s, gen_new_label(s));
|
label_over = gen_new_label(s);
|
||||||
new_args[4] = tcg_invert_cond(new_args[4]);
|
new_args[4] = tcg_invert_cond(new_args[4]);
|
||||||
new_args[5] = label_over;
|
new_args[5] = label_arg(s, label_over);
|
||||||
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
tcg_out_brcond2(s, new_args, const_args+1, 1);
|
||||||
|
|
||||||
tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
|
tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
|
||||||
|
@ -1108,7 +1108,7 @@ static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
|
||||||
if (have_cmov) {
|
if (have_cmov) {
|
||||||
tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
|
tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
|
||||||
} else {
|
} else {
|
||||||
int over = label_arg(s, gen_new_label(s));
|
TCGLabel *over = gen_new_label(s);
|
||||||
tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
|
tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
|
||||||
tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
|
tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
|
||||||
tcg_out_label(s, over, s->code_ptr);
|
tcg_out_label(s, over, s->code_ptr);
|
||||||
|
@ -1851,7 +1851,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
s->tb_next_offset[args[0]] = tcg_current_code_size(s);
|
s->tb_next_offset[args[0]] = tcg_current_code_size(s);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tcg_out_jxx(s, JCC_JMP, args[0], 0);
|
tcg_out_jxx(s, JCC_JMP, arg_label(s, args[0]), 0);
|
||||||
break;
|
break;
|
||||||
OP_32_64(ld8u):
|
OP_32_64(ld8u):
|
||||||
/* Note that we can ignore REXW for the zero-extend to 64-bit. */
|
/* Note that we can ignore REXW for the zero-extend to 64-bit. */
|
||||||
|
@ -2012,7 +2012,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
|
tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
|
||||||
args[3], 0);
|
arg_label(s, args[3]), 0);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
tcg_out_setcond32(s, args[3], args[0], args[1],
|
tcg_out_setcond32(s, args[3], args[0], args[1],
|
||||||
|
@ -2120,7 +2120,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
|
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
|
tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
|
||||||
args[3], 0);
|
arg_label(s, args[3]), 0);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
tcg_out_setcond64(s, args[3], args[0], args[1],
|
tcg_out_setcond64(s, args[3], args[0], args[1],
|
||||||
|
|
|
@ -635,7 +635,7 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
|
static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
TCGReg arg2, int label_index)
|
TCGReg arg2, TCGLabel *l)
|
||||||
{
|
{
|
||||||
static const MIPSInsn b_zero[16] = {
|
static const MIPSInsn b_zero[16] = {
|
||||||
[TCG_COND_LT] = OPC_BLTZ,
|
[TCG_COND_LT] = OPC_BLTZ,
|
||||||
|
@ -644,7 +644,6 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
[TCG_COND_GE] = OPC_BGEZ,
|
[TCG_COND_GE] = OPC_BGEZ,
|
||||||
};
|
};
|
||||||
|
|
||||||
TCGLabel *l;
|
|
||||||
MIPSInsn s_opc = OPC_SLTU;
|
MIPSInsn s_opc = OPC_SLTU;
|
||||||
MIPSInsn b_opc;
|
MIPSInsn b_opc;
|
||||||
int cmp_map;
|
int cmp_map;
|
||||||
|
@ -692,11 +691,10 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
}
|
}
|
||||||
|
|
||||||
tcg_out_opc_br(s, b_opc, arg1, arg2);
|
tcg_out_opc_br(s, b_opc, arg1, arg2);
|
||||||
l = &s->labels[label_index];
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
|
reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, label_index, 0);
|
tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
|
||||||
}
|
}
|
||||||
tcg_out_nop(s);
|
tcg_out_nop(s);
|
||||||
}
|
}
|
||||||
|
@ -765,7 +763,7 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||||
TCGReg bl, TCGReg bh, int label_index)
|
TCGReg bl, TCGReg bh, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGCond b_cond = TCG_COND_NE;
|
TCGCond b_cond = TCG_COND_NE;
|
||||||
TCGReg tmp = TCG_TMP1;
|
TCGReg tmp = TCG_TMP1;
|
||||||
|
@ -790,7 +788,7 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, label_index);
|
tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||||
|
@ -1367,7 +1365,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
s->tb_next_offset[a0] = tcg_current_code_size(s);
|
s->tb_next_offset[a0] = tcg_current_code_size(s);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, a0);
|
tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO,
|
||||||
|
arg_label(s, a0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_ld8u_i32:
|
case INDEX_op_ld8u_i32:
|
||||||
|
@ -1527,10 +1526,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tcg_out_brcond(s, a2, a0, a1, args[3]);
|
tcg_out_brcond(s, a2, a0, a1, arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_brcond2_i32:
|
case INDEX_op_brcond2_i32:
|
||||||
tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], args[5]);
|
tcg_out_brcond2(s, args[4], a0, a1, a2, args[3], arg_label(s, args[5]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_movcond_i32:
|
case INDEX_op_movcond_i32:
|
||||||
|
|
|
@ -1100,24 +1100,22 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_bc(TCGContext *s, int bc, int label_index)
|
static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label_index];
|
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
|
tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
|
||||||
} else {
|
} else {
|
||||||
tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
|
tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
|
||||||
tcg_out_bc_noaddr(s, bc);
|
tcg_out_bc_noaddr(s, bc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
|
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
|
||||||
TCGArg arg1, TCGArg arg2, int const_arg2,
|
TCGArg arg1, TCGArg arg2, int const_arg2,
|
||||||
int label_index, TCGType type)
|
TCGLabel *l, TCGType type)
|
||||||
{
|
{
|
||||||
tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
|
tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
|
||||||
tcg_out_bc(s, tcg_to_bc[cond], label_index);
|
tcg_out_bc(s, tcg_to_bc[cond], l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
|
static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
|
||||||
|
@ -1242,7 +1240,7 @@ static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
|
||||||
const int *const_args)
|
const int *const_args)
|
||||||
{
|
{
|
||||||
tcg_out_cmp2(s, args, const_args);
|
tcg_out_cmp2(s, args, const_args);
|
||||||
tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, args[5]);
|
tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(s, args[5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
|
void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
|
||||||
|
@ -1866,12 +1864,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[args[0]];
|
TCGLabel *l = arg_label(s, args[0]);
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
tcg_out_b(s, 0, l->u.value_ptr);
|
tcg_out_b(s, 0, l->u.value_ptr);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
|
tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
|
||||||
tcg_out_b_noaddr(s, B);
|
tcg_out_b_noaddr(s, B);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2079,11 +2077,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
|
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
|
||||||
args[3], TCG_TYPE_I32);
|
arg_label(s, args[3]), TCG_TYPE_I32);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
|
tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
|
||||||
args[3], TCG_TYPE_I64);
|
arg_label(s, args[3]), TCG_TYPE_I64);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_brcond2_i32:
|
case INDEX_op_brcond2_i32:
|
||||||
tcg_out_brcond2(s, args, const_args);
|
tcg_out_brcond2(s, args, const_args);
|
||||||
|
|
|
@ -1274,26 +1274,24 @@ static void tgen_gotoi(TCGContext *s, int cc, tcg_insn_unit *dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tgen_branch(TCGContext *s, int cc, int labelno)
|
static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel* l = &s->labels[labelno];
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
tgen_gotoi(s, cc, l->u.value_ptr);
|
tgen_gotoi(s, cc, l->u.value_ptr);
|
||||||
} else if (USE_LONG_BRANCHES) {
|
} else if (USE_LONG_BRANCHES) {
|
||||||
tcg_out16(s, RIL_BRCL | (cc << 4));
|
tcg_out16(s, RIL_BRCL | (cc << 4));
|
||||||
tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
|
tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, l, -2);
|
||||||
s->code_ptr += 2;
|
s->code_ptr += 2;
|
||||||
} else {
|
} else {
|
||||||
tcg_out16(s, RI_BRC | (cc << 4));
|
tcg_out16(s, RI_BRC | (cc << 4));
|
||||||
tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
|
tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, l, -2);
|
||||||
s->code_ptr += 1;
|
s->code_ptr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
|
static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
TCGReg r1, TCGReg r2, int labelno)
|
TCGReg r1, TCGReg r2, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel* l = &s->labels[labelno];
|
|
||||||
intptr_t off;
|
intptr_t off;
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
|
@ -1301,7 +1299,7 @@ static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
} else {
|
} else {
|
||||||
/* We need to keep the offset unchanged for retranslation. */
|
/* We need to keep the offset unchanged for retranslation. */
|
||||||
off = s->code_ptr[1];
|
off = s->code_ptr[1];
|
||||||
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, labelno, -2);
|
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
|
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
|
||||||
|
@ -1310,9 +1308,8 @@ static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
|
static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
TCGReg r1, int i2, int labelno)
|
TCGReg r1, int i2, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel* l = &s->labels[labelno];
|
|
||||||
tcg_target_long off;
|
tcg_target_long off;
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
|
@ -1320,7 +1317,7 @@ static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
} else {
|
} else {
|
||||||
/* We need to keep the offset unchanged for retranslation. */
|
/* We need to keep the offset unchanged for retranslation. */
|
||||||
off = s->code_ptr[1];
|
off = s->code_ptr[1];
|
||||||
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, labelno, -2);
|
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
|
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
|
||||||
|
@ -1329,7 +1326,7 @@ static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
|
static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
|
||||||
TCGReg r1, TCGArg c2, int c2const, int labelno)
|
TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
|
@ -1344,7 +1341,7 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
|
||||||
opc = (type == TCG_TYPE_I32
|
opc = (type == TCG_TYPE_I32
|
||||||
? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
|
? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
|
||||||
: (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
|
: (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
|
||||||
tgen_compare_branch(s, opc, cc, r1, c2, labelno);
|
tgen_compare_branch(s, opc, cc, r1, c2, l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1370,13 +1367,13 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in_range) {
|
if (in_range) {
|
||||||
tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
|
tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cc = tgen_cmp(s, type, c, r1, c2, c2const);
|
cc = tgen_cmp(s, type, c, r1, c2, c2const);
|
||||||
tgen_branch(s, cc, labelno);
|
tgen_branch(s, cc, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
|
static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
|
||||||
|
@ -1904,12 +1901,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tgen_branch(s, S390_CC_ALWAYS, args[0]);
|
tgen_branch(s, S390_CC_ALWAYS, arg_label(s, args[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
|
tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
|
||||||
args[1], const_args[1], args[3]);
|
args[1], const_args[1], arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
|
tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
|
||||||
|
@ -2126,7 +2123,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
|
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
|
tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
|
||||||
args[1], const_args[1], args[3]);
|
args[1], const_args[1], arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
|
tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
|
||||||
|
|
|
@ -569,9 +569,8 @@ static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
|
||||||
tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
|
tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_bpcc(TCGContext *s, int scond, int flags, int label)
|
static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label];
|
|
||||||
int off19;
|
int off19;
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
|
@ -579,7 +578,7 @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, int label)
|
||||||
} else {
|
} else {
|
||||||
/* Make sure to preserve destinations during retranslation. */
|
/* Make sure to preserve destinations during retranslation. */
|
||||||
off19 = *s->code_ptr & INSN_OFF19(-1);
|
off19 = *s->code_ptr & INSN_OFF19(-1);
|
||||||
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label, 0);
|
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, l, 0);
|
||||||
}
|
}
|
||||||
tcg_out_bpcc0(s, scond, flags, off19);
|
tcg_out_bpcc0(s, scond, flags, off19);
|
||||||
}
|
}
|
||||||
|
@ -590,10 +589,10 @@ static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
|
static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
int32_t arg2, int const_arg2, int label)
|
int32_t arg2, int const_arg2, TCGLabel *l)
|
||||||
{
|
{
|
||||||
tcg_out_cmp(s, arg1, arg2, const_arg2);
|
tcg_out_cmp(s, arg1, arg2, const_arg2);
|
||||||
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, label);
|
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, l);
|
||||||
tcg_out_nop(s);
|
tcg_out_nop(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,11 +613,10 @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
|
static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
int32_t arg2, int const_arg2, int label)
|
int32_t arg2, int const_arg2, TCGLabel *l)
|
||||||
{
|
{
|
||||||
/* For 64-bit signed comparisons vs zero, we can avoid the compare. */
|
/* For 64-bit signed comparisons vs zero, we can avoid the compare. */
|
||||||
if (arg2 == 0 && !is_unsigned_cond(cond)) {
|
if (arg2 == 0 && !is_unsigned_cond(cond)) {
|
||||||
TCGLabel *l = &s->labels[label];
|
|
||||||
int off16;
|
int off16;
|
||||||
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
|
@ -626,13 +624,13 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
|
||||||
} else {
|
} else {
|
||||||
/* Make sure to preserve destinations during retranslation. */
|
/* Make sure to preserve destinations during retranslation. */
|
||||||
off16 = *s->code_ptr & INSN_OFF16(-1);
|
off16 = *s->code_ptr & INSN_OFF16(-1);
|
||||||
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0);
|
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, l, 0);
|
||||||
}
|
}
|
||||||
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
|
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
|
||||||
| INSN_COND(tcg_cond_to_rcond[cond]) | off16);
|
| INSN_COND(tcg_cond_to_rcond[cond]) | off16);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_cmp(s, arg1, arg2, const_arg2);
|
tcg_out_cmp(s, arg1, arg2, const_arg2);
|
||||||
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label);
|
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
|
||||||
}
|
}
|
||||||
tcg_out_nop(s);
|
tcg_out_nop(s);
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1241,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
s->tb_next_offset[a0] = tcg_current_code_size(s);
|
s->tb_next_offset[a0] = tcg_current_code_size(s);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_br:
|
case INDEX_op_br:
|
||||||
tcg_out_bpcc(s, COND_A, BPCC_PT, a0);
|
tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(s, a0));
|
||||||
tcg_out_nop(s);
|
tcg_out_nop(s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1329,7 +1327,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
case INDEX_op_brcond_i32:
|
||||||
tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], args[3]);
|
tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i32:
|
case INDEX_op_setcond_i32:
|
||||||
tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
|
tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
|
||||||
|
@ -1420,7 +1418,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INDEX_op_brcond_i64:
|
case INDEX_op_brcond_i64:
|
||||||
tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], args[3]);
|
tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(s, args[3]));
|
||||||
break;
|
break;
|
||||||
case INDEX_op_setcond_i64:
|
case INDEX_op_setcond_i64:
|
||||||
tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
|
tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
|
||||||
|
|
|
@ -201,12 +201,10 @@ static QEMU_UNUSED_FUNC inline void tcg_patch64(tcg_insn_unit *p,
|
||||||
/* label relocation processing */
|
/* label relocation processing */
|
||||||
|
|
||||||
static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
|
static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
|
||||||
int label_index, intptr_t addend)
|
TCGLabel *l, intptr_t addend)
|
||||||
{
|
{
|
||||||
TCGLabel *l;
|
|
||||||
TCGRelocation *r;
|
TCGRelocation *r;
|
||||||
|
|
||||||
l = &s->labels[label_index];
|
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
/* FIXME: This may break relocations on RISC targets that
|
/* FIXME: This may break relocations on RISC targets that
|
||||||
modify instruction fields in place. The caller may not have
|
modify instruction fields in place. The caller may not have
|
||||||
|
@ -223,9 +221,8 @@ static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr)
|
static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
|
||||||
{
|
{
|
||||||
TCGLabel *l = &s->labels[label_index];
|
|
||||||
intptr_t value = (intptr_t)ptr;
|
intptr_t value = (intptr_t)ptr;
|
||||||
TCGRelocation *r;
|
TCGRelocation *r;
|
||||||
|
|
||||||
|
@ -2397,7 +2394,7 @@ static inline int tcg_gen_code_common(TCGContext *s,
|
||||||
break;
|
break;
|
||||||
case INDEX_op_set_label:
|
case INDEX_op_set_label:
|
||||||
tcg_reg_alloc_bb_end(s, s->reserved_regs);
|
tcg_reg_alloc_bb_end(s, s->reserved_regs);
|
||||||
tcg_out_label(s, args[0], s->code_ptr);
|
tcg_out_label(s, arg_label(s, args[0]), s->code_ptr);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_call:
|
case INDEX_op_call:
|
||||||
tcg_reg_alloc_call(s, op->callo, op->calli, args,
|
tcg_reg_alloc_call(s, op->callo, op->calli, args,
|
||||||
|
|
Loading…
Reference in a new issue