提交 cf066674 编写于 作者: R Richard Henderson

tcg: Make call address a constant parameter

Avoid allocating a tcg temporary to hold the constant address,
and instead place it directly into the op_call arguments.

At the same time, convert to the newly introduced tcg_out_call
backend function, rather than invoking tcg_out_op for the call.
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 dddbb2e1
...@@ -513,12 +513,8 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2) ...@@ -513,12 +513,8 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
TCGArg *args, TCGOpDef *tcg_op_defs) TCGArg *args, TCGOpDef *tcg_op_defs)
{ {
int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args; int nb_ops, op_index, nb_temps, nb_globals;
tcg_target_ulong mask, affected;
TCGOpcode op;
const TCGOpDef *def;
TCGArg *gen_args; TCGArg *gen_args;
TCGArg tmp;
/* Array VALS has an element for each temp. /* Array VALS has an element for each temp.
If this temp holds a constant then its value is kept in VALS' element. If this temp holds a constant then its value is kept in VALS' element.
...@@ -532,22 +528,27 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -532,22 +528,27 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
nb_ops = tcg_opc_ptr - s->gen_opc_buf; nb_ops = tcg_opc_ptr - s->gen_opc_buf;
gen_args = args; gen_args = args;
for (op_index = 0; op_index < nb_ops; op_index++) { for (op_index = 0; op_index < nb_ops; op_index++) {
op = s->gen_opc_buf[op_index]; TCGOpcode op = s->gen_opc_buf[op_index];
def = &tcg_op_defs[op]; const TCGOpDef *def = &tcg_op_defs[op];
/* Do copy propagation */ tcg_target_ulong mask, affected;
int nb_oargs, nb_iargs, nb_args, i;
TCGArg tmp;
if (op == INDEX_op_call) { if (op == INDEX_op_call) {
int nb_oargs = args[0] >> 16; *gen_args++ = tmp = *args++;
int nb_iargs = args[0] & 0xffff; nb_oargs = tmp >> 16;
for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) { nb_iargs = tmp & 0xffff;
if (temps[args[i]].state == TCG_TEMP_COPY) { nb_args = nb_oargs + nb_iargs + def->nb_cargs;
args[i] = find_better_copy(s, args[i]);
}
}
} else { } else {
for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) { nb_oargs = def->nb_oargs;
if (temps[args[i]].state == TCG_TEMP_COPY) { nb_iargs = def->nb_iargs;
args[i] = find_better_copy(s, args[i]); nb_args = def->nb_args;
} }
/* Do copy propagation */
for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
if (temps[args[i]].state == TCG_TEMP_COPY) {
args[i] = find_better_copy(s, args[i]);
} }
} }
...@@ -882,7 +883,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -882,7 +883,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(qemu_ld): CASE_OP_32_64(qemu_ld):
{ {
TCGMemOp mop = args[def->nb_oargs + def->nb_iargs]; TCGMemOp mop = args[nb_oargs + nb_iargs];
if (!(mop & MO_SIGN)) { if (!(mop & MO_SIGN)) {
mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1; mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1;
} }
...@@ -900,15 +901,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -900,15 +901,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
} }
if (mask == 0) { if (mask == 0) {
assert(def->nb_oargs == 1); assert(nb_oargs == 1);
s->gen_opc_buf[op_index] = op_to_movi(op); s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], 0); tcg_opt_gen_movi(gen_args, args[0], 0);
args += def->nb_oargs + def->nb_iargs + def->nb_cargs; args += nb_args;
gen_args += 2; gen_args += 2;
continue; continue;
} }
if (affected == 0) { if (affected == 0) {
assert(def->nb_oargs == 1); assert(nb_oargs == 1);
if (temps_are_copies(args[0], args[1])) { if (temps_are_copies(args[0], args[1])) {
s->gen_opc_buf[op_index] = INDEX_op_nop; s->gen_opc_buf[op_index] = INDEX_op_nop;
} else if (temps[args[1]].state != TCG_TEMP_CONST) { } else if (temps[args[1]].state != TCG_TEMP_CONST) {
...@@ -920,7 +921,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -920,7 +921,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
tcg_opt_gen_movi(gen_args, args[0], temps[args[1]].val); tcg_opt_gen_movi(gen_args, args[0], temps[args[1]].val);
gen_args += 2; gen_args += 2;
} }
args += def->nb_iargs + 1; args += nb_args;
continue; continue;
} }
...@@ -1246,24 +1247,13 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -1246,24 +1247,13 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
break; break;
case INDEX_op_call: case INDEX_op_call:
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); if (!(args[nb_oargs + nb_iargs + 1]
if (!(args[nb_call_args + 1] & (TCG_CALL_NO_READ_GLOBALS | & (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
TCG_CALL_NO_WRITE_GLOBALS))) {
for (i = 0; i < nb_globals; i++) { for (i = 0; i < nb_globals; i++) {
reset_temp(i); reset_temp(i);
} }
} }
for (i = 0; i < (args[0] >> 16); i++) { goto do_reset_output;
reset_temp(args[i + 1]);
}
i = nb_call_args + 3;
while (i) {
*gen_args = *args;
args++;
gen_args++;
i--;
}
break;
default: default:
do_default: do_default:
...@@ -1275,7 +1265,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -1275,7 +1265,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
if (def->flags & TCG_OPF_BB_END) { if (def->flags & TCG_OPF_BB_END) {
reset_all_temps(nb_temps); reset_all_temps(nb_temps);
} else { } else {
for (i = 0; i < def->nb_oargs; i++) { do_reset_output:
for (i = 0; i < nb_oargs; i++) {
reset_temp(args[i]); reset_temp(args[i]);
/* Save the corresponding known-zero bits mask for the /* Save the corresponding known-zero bits mask for the
first output argument (only one supported so far). */ first output argument (only one supported so far). */
...@@ -1284,11 +1275,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, ...@@ -1284,11 +1275,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
} }
} }
} }
for (i = 0; i < def->nb_args; i++) { for (i = 0; i < nb_args; i++) {
gen_args[i] = args[i]; gen_args[i] = args[i];
} }
args += def->nb_args; args += nb_args;
gen_args += def->nb_args; gen_args += nb_args;
break; break;
} }
} }
......
...@@ -390,11 +390,7 @@ static inline int tcg_gen_sizemask(int n, int is_64bit, int is_signed) ...@@ -390,11 +390,7 @@ static inline int tcg_gen_sizemask(int n, int is_64bit, int is_signed)
static inline void tcg_gen_helperN(void *func, int flags, int sizemask, static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
TCGArg ret, int nargs, TCGArg *args) TCGArg ret, int nargs, TCGArg *args)
{ {
TCGv_ptr fn; tcg_gen_callN(&tcg_ctx, func, flags, sizemask, ret, nargs, args);
fn = tcg_const_ptr(func);
tcg_gen_callN(&tcg_ctx, fn, flags, sizemask, ret,
nargs, args);
tcg_temp_free_ptr(fn);
} }
/* Note: Both tcg_gen_helper32() and tcg_gen_helper64() are currently /* Note: Both tcg_gen_helper32() and tcg_gen_helper64() are currently
...@@ -405,29 +401,23 @@ static inline void tcg_gen_helperN(void *func, int flags, int sizemask, ...@@ -405,29 +401,23 @@ static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
static inline void tcg_gen_helper32(void *func, int sizemask, TCGv_i32 ret, static inline void tcg_gen_helper32(void *func, int sizemask, TCGv_i32 ret,
TCGv_i32 a, TCGv_i32 b) TCGv_i32 a, TCGv_i32 b)
{ {
TCGv_ptr fn;
TCGArg args[2]; TCGArg args[2];
fn = tcg_const_ptr(func);
args[0] = GET_TCGV_I32(a); args[0] = GET_TCGV_I32(a);
args[1] = GET_TCGV_I32(b); args[1] = GET_TCGV_I32(b);
tcg_gen_callN(&tcg_ctx, fn, tcg_gen_callN(&tcg_ctx, func,
TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_SIDE_EFFECTS, TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_SIDE_EFFECTS,
sizemask, GET_TCGV_I32(ret), 2, args); sizemask, GET_TCGV_I32(ret), 2, args);
tcg_temp_free_ptr(fn);
} }
static inline void tcg_gen_helper64(void *func, int sizemask, TCGv_i64 ret, static inline void tcg_gen_helper64(void *func, int sizemask, TCGv_i64 ret,
TCGv_i64 a, TCGv_i64 b) TCGv_i64 a, TCGv_i64 b)
{ {
TCGv_ptr fn;
TCGArg args[2]; TCGArg args[2];
fn = tcg_const_ptr(func);
args[0] = GET_TCGV_I64(a); args[0] = GET_TCGV_I64(a);
args[1] = GET_TCGV_I64(b); args[1] = GET_TCGV_I64(b);
tcg_gen_callN(&tcg_ctx, fn, tcg_gen_callN(&tcg_ctx, func,
TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_SIDE_EFFECTS, TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_SIDE_EFFECTS,
sizemask, GET_TCGV_I64(ret), 2, args); sizemask, GET_TCGV_I64(ret), 2, args);
tcg_temp_free_ptr(fn);
} }
/* 32 bit ops */ /* 32 bit ops */
......
...@@ -40,7 +40,7 @@ DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT) ...@@ -40,7 +40,7 @@ DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT)
DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
/* variable number of parameters */ /* variable number of parameters */
DEF(call, 0, 1, 2, TCG_OPF_CALL_CLOBBER) DEF(call, 0, 0, 3, TCG_OPF_CALL_CLOBBER)
DEF(br, 0, 0, 1, TCG_OPF_BB_END) DEF(br, 0, 0, 1, TCG_OPF_BB_END)
......
...@@ -101,6 +101,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, ...@@ -101,6 +101,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
const int *const_args); const int *const_args);
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
intptr_t arg2); intptr_t arg2);
static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
static int tcg_target_const_match(tcg_target_long val, TCGType type, static int tcg_target_const_match(tcg_target_long val, TCGType type,
const TCGArgConstraint *arg_ct); const TCGArgConstraint *arg_ct);
static void tcg_out_tb_init(TCGContext *s); static void tcg_out_tb_init(TCGContext *s);
...@@ -705,7 +706,7 @@ int tcg_check_temp_count(void) ...@@ -705,7 +706,7 @@ int tcg_check_temp_count(void)
/* Note: we convert the 64 bit args to 32 bit and do some alignment /* Note: we convert the 64 bit args to 32 bit and do some alignment
and endian swap. Maybe it would be better to do the alignment and endian swap. Maybe it would be better to do the alignment
and endian swap in tcg_reg_alloc_call(). */ and endian swap in tcg_reg_alloc_call(). */
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, void tcg_gen_callN(TCGContext *s, void *func, unsigned int flags,
int sizemask, TCGArg ret, int nargs, TCGArg *args) int sizemask, TCGArg ret, int nargs, TCGArg *args)
{ {
int i; int i;
...@@ -832,11 +833,10 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, ...@@ -832,11 +833,10 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
*s->gen_opparam_ptr++ = args[i]; *s->gen_opparam_ptr++ = args[i];
real_args++; real_args++;
} }
*s->gen_opparam_ptr++ = GET_TCGV_PTR(func); *s->gen_opparam_ptr++ = (uintptr_t)func;
*s->gen_opparam_ptr++ = flags; *s->gen_opparam_ptr++ = flags;
*nparam = (nb_rets << 16) | (real_args + 1); *nparam = (nb_rets << 16) | real_args;
/* total parameters, needed to go backward in the instruction stream */ /* total parameters, needed to go backward in the instruction stream */
*s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3; *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
...@@ -1243,49 +1243,21 @@ void tcg_dump_ops(TCGContext *s) ...@@ -1243,49 +1243,21 @@ void tcg_dump_ops(TCGContext *s)
nb_iargs = arg & 0xffff; nb_iargs = arg & 0xffff;
nb_cargs = def->nb_cargs; nb_cargs = def->nb_cargs;
qemu_log(" %s ", def->name); /* function name, flags, out args */
qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
/* function name */ tcg_find_helper(s, args[nb_oargs + nb_iargs]),
qemu_log("%s", args[nb_oargs + nb_iargs + 1], nb_oargs);
tcg_get_arg_str_idx(s, buf, sizeof(buf), for (i = 0; i < nb_oargs; i++) {
args[nb_oargs + nb_iargs - 1])); qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
/* flags */
qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]);
/* nb out args */
qemu_log(",$%d", nb_oargs);
for(i = 0; i < nb_oargs; i++) {
qemu_log(",");
qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[i])); args[i]));
} }
for(i = 0; i < (nb_iargs - 1); i++) { for (i = 0; i < nb_iargs; i++) {
qemu_log(","); TCGArg arg = args[nb_oargs + i];
if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { const char *t = "<dummy>";
qemu_log("<dummy>"); if (arg != TCG_CALL_DUMMY_ARG) {
} else { t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
args[nb_oargs + i]));
}
}
} else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
tcg_target_ulong val;
const char *name;
nb_oargs = def->nb_oargs;
nb_iargs = def->nb_iargs;
nb_cargs = def->nb_cargs;
qemu_log(" %s %s,$", def->name,
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
val = args[1];
name = tcg_find_helper(s, val);
if (name) {
qemu_log("%s", name);
} else {
if (c == INDEX_op_movi_i32) {
qemu_log("0x%x", (uint32_t)val);
} else {
qemu_log("0x%" PRIx64 , (uint64_t)val);
} }
qemu_log(",%s", t);
} }
} else { } else {
qemu_log(" %s ", def->name); qemu_log(" %s ", def->name);
...@@ -1548,9 +1520,9 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps, ...@@ -1548,9 +1520,9 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
temporaries are removed. */ temporaries are removed. */
static void tcg_liveness_analysis(TCGContext *s) static void tcg_liveness_analysis(TCGContext *s)
{ {
int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops; int i, op_index, nb_args, nb_iargs, nb_oargs, nb_ops;
TCGOpcode op, op_new, op_new2; TCGOpcode op, op_new, op_new2;
TCGArg *args; TCGArg *args, arg;
const TCGOpDef *def; const TCGOpDef *def;
uint8_t *dead_temps, *mem_temps; uint8_t *dead_temps, *mem_temps;
uint16_t dead_args; uint16_t dead_args;
...@@ -1580,15 +1552,15 @@ static void tcg_liveness_analysis(TCGContext *s) ...@@ -1580,15 +1552,15 @@ static void tcg_liveness_analysis(TCGContext *s)
nb_args = args[-1]; nb_args = args[-1];
args -= nb_args; args -= nb_args;
nb_iargs = args[0] & 0xffff; arg = *args++;
nb_oargs = args[0] >> 16; nb_iargs = arg & 0xffff;
args++; nb_oargs = arg >> 16;
call_flags = args[nb_oargs + nb_iargs]; call_flags = args[nb_oargs + nb_iargs + 1];
/* pure functions can be removed if their result is not /* pure functions can be removed if their result is not
used */ used */
if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) { if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
for(i = 0; i < nb_oargs; i++) { for (i = 0; i < nb_oargs; i++) {
arg = args[i]; arg = args[i];
if (!dead_temps[arg] || mem_temps[arg]) { if (!dead_temps[arg] || mem_temps[arg]) {
goto do_not_remove_call; goto do_not_remove_call;
...@@ -1602,7 +1574,7 @@ static void tcg_liveness_analysis(TCGContext *s) ...@@ -1602,7 +1574,7 @@ static void tcg_liveness_analysis(TCGContext *s)
/* output args are dead */ /* output args are dead */
dead_args = 0; dead_args = 0;
sync_args = 0; sync_args = 0;
for(i = 0; i < nb_oargs; i++) { for (i = 0; i < nb_oargs; i++) {
arg = args[i]; arg = args[i];
if (dead_temps[arg]) { if (dead_temps[arg]) {
dead_args |= (1 << i); dead_args |= (1 << i);
...@@ -1625,7 +1597,7 @@ static void tcg_liveness_analysis(TCGContext *s) ...@@ -1625,7 +1597,7 @@ static void tcg_liveness_analysis(TCGContext *s)
} }
/* input args are live */ /* input args are live */
for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
arg = args[i]; arg = args[i];
if (arg != TCG_CALL_DUMMY_ARG) { if (arg != TCG_CALL_DUMMY_ARG) {
if (dead_temps[arg]) { if (dead_temps[arg]) {
...@@ -2372,26 +2344,27 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, ...@@ -2372,26 +2344,27 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
uint16_t dead_args, uint8_t sync_args) uint16_t dead_args, uint8_t sync_args)
{ {
int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
TCGArg arg, func_arg; TCGArg arg;
TCGTemp *ts; TCGTemp *ts;
intptr_t stack_offset; intptr_t stack_offset;
size_t call_stack_size; size_t call_stack_size;
uintptr_t func_addr; tcg_insn_unit *func_addr;
int const_func_arg, allocate_args; int allocate_args;
TCGRegSet allocated_regs; TCGRegSet allocated_regs;
const TCGArgConstraint *arg_ct;
arg = *args++; arg = *args++;
nb_oargs = arg >> 16; nb_oargs = arg >> 16;
nb_iargs = arg & 0xffff; nb_iargs = arg & 0xffff;
nb_params = nb_iargs - 1; nb_params = nb_iargs;
flags = args[nb_oargs + nb_iargs]; func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
flags = args[nb_oargs + nb_iargs + 1];
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs); nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
if (nb_regs > nb_params) if (nb_regs > nb_params) {
nb_regs = nb_params; nb_regs = nb_params;
}
/* assign stack slots first */ /* assign stack slots first */
call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
...@@ -2459,40 +2432,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, ...@@ -2459,40 +2432,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
} }
} }
/* assign function address */
func_arg = args[nb_oargs + nb_iargs - 1];
arg_ct = &def->args_ct[0];
ts = &s->temps[func_arg];
func_addr = ts->val;
const_func_arg = 0;
if (ts->val_type == TEMP_VAL_MEM) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_REG) {
reg = ts->reg;
if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_mov(s, ts->type, reg, ts->reg);
}
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
} else if (ts->val_type == TEMP_VAL_CONST) {
if (tcg_target_const_match(func_addr, ts->type, arg_ct)) {
const_func_arg = 1;
func_arg = func_addr;
} else {
reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
tcg_out_movi(s, ts->type, reg, func_addr);
func_arg = reg;
tcg_regset_set_reg(allocated_regs, reg);
}
} else {
tcg_abort();
}
/* mark dead temporaries and free the associated registers */ /* mark dead temporaries and free the associated registers */
for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
if (IS_DEAD_ARG(i)) { if (IS_DEAD_ARG(i)) {
...@@ -2517,7 +2456,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, ...@@ -2517,7 +2456,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
save_globals(s, allocated_regs); save_globals(s, allocated_regs);
} }
tcg_out_op(s, opc, &func_arg, &const_func_arg); tcg_out_call(s, func_addr);
/* assign output registers and emit moves if needed */ /* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) { for(i = 0; i < nb_oargs; i++) {
......
...@@ -725,7 +725,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); ...@@ -725,7 +725,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T)) #define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
#endif #endif
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, void tcg_gen_callN(TCGContext *s, void *func, unsigned int flags,
int sizemask, TCGArg ret, int nargs, TCGArg *args); int sizemask, TCGArg ret, int nargs, TCGArg *args);
void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册