DEF2(macro_end, 0, 0, 2, 0)
DEF2(macro_goto, 0, 0, 3, 0)
+DEF2(discard, 1, 0, 0, 0)
+
DEF2(set_label, 0, 0, 1, 0)
-DEF2(call, 0, 1, 2, 0) /* variable number of parameters */
-DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END)
-DEF2(br, 0, 0, 1, TCG_OPF_BB_END)
+DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
+DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
DEF2(mov_i32, 1, 1, 0, 0)
DEF2(movi_i32, 1, 0, 1, 0)
DEF2(ld16u_i32, 1, 1, 1, 0)
DEF2(ld16s_i32, 1, 1, 1, 0)
DEF2(ld_i32, 1, 1, 1, 0)
-DEF2(st8_i32, 0, 2, 1, 0)
-DEF2(st16_i32, 0, 2, 1, 0)
-DEF2(st_i32, 0, 2, 1, 0)
+DEF2(st8_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF2(st16_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF2(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
/* arith */
DEF2(add_i32, 1, 2, 0, 0)
DEF2(sub_i32, 1, 2, 0, 0)
DEF2(shr_i32, 1, 2, 0, 0)
DEF2(sar_i32, 1, 2, 0, 0)
-DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END)
+DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
#if TCG_TARGET_REG_BITS == 32
DEF2(add2_i32, 2, 4, 0, 0)
DEF2(sub2_i32, 2, 4, 0, 0)
-DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END)
+DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
DEF2(mulu2_i32, 2, 2, 0, 0)
#endif
#ifdef TCG_TARGET_HAS_ext8s_i32
DEF2(ld32u_i64, 1, 1, 1, 0)
DEF2(ld32s_i64, 1, 1, 1, 0)
DEF2(ld_i64, 1, 1, 1, 0)
-DEF2(st8_i64, 0, 2, 1, 0)
-DEF2(st16_i64, 0, 2, 1, 0)
-DEF2(st32_i64, 0, 2, 1, 0)
-DEF2(st_i64, 0, 2, 1, 0)
+DEF2(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF2(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF2(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF2(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
/* arith */
DEF2(add_i64, 1, 2, 0, 0)
DEF2(sub_i64, 1, 2, 0, 0)
DEF2(shr_i64, 1, 2, 0, 0)
DEF2(sar_i64, 1, 2, 0, 0)
-DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END)
+DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
#ifdef TCG_TARGET_HAS_ext8s_i64
DEF2(ext8s_i64, 1, 1, 0, 0)
#endif
#endif
/* QEMU specific */
-DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END)
+DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
/* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op
constants must be defined */
#if TCG_TARGET_REG_BITS == 32
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#if TARGET_LONG_BITS == 32
-DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#else
-DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif
#else /* TCG_TARGET_REG_BITS == 32 */
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
-DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER)
+DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
+DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
#endif /* TCG_TARGET_REG_BITS != 32 */
ts = &s->temps[s->nb_temps];
ts->base_type = type;
ts->type = TCG_TYPE_I32;
+ ts->fixed_reg = 0;
ts->val_type = TEMP_VAL_DEAD;
ts->mem_allocated = 0;
ts->name = NULL;
ts->base_type = TCG_TYPE_I32;
ts->type = TCG_TYPE_I32;
ts->val_type = TEMP_VAL_DEAD;
+ ts->fixed_reg = 0;
ts->mem_allocated = 0;
ts->name = NULL;
s->nb_temps += 2;
ts = &s->temps[s->nb_temps];
ts->base_type = type;
ts->type = type;
+ ts->fixed_reg = 0;
ts->val_type = TEMP_VAL_DEAD;
ts->mem_allocated = 0;
ts->name = NULL;
assert(oarg < def->nb_oargs);
assert(def->args_ct[oarg].ct & TCG_CT_REG);
/* TCG_CT_ALIAS is for the output arguments. The input
- argument is tagged with TCG_CT_IALIAS for
- informative purposes. */
+ argument is tagged with TCG_CT_IALIAS. */
def->args_ct[i] = def->args_ct[oarg];
- def->args_ct[oarg].ct = i | TCG_CT_ALIAS;
+ def->args_ct[oarg].ct = TCG_CT_ALIAS;
+ def->args_ct[oarg].alias_index = i;
def->args_ct[i].ct |= TCG_CT_IALIAS;
+ def->args_ct[i].alias_index = oarg;
} else {
for(;;) {
if (*ct_str == '\0')
nb_args = args[-1];
args -= nb_args;
break;
+ case INDEX_op_discard:
+ args--;
+ /* mark the temporary as dead */
+ dead_temps[args[0]] = 1;
+ break;
case INDEX_op_macro_2:
{
int dead_args[2], macro_id;
nb_oargs = def->nb_oargs;
/* Test if the operation can be removed because all
- its outputs are dead. We may add a flag to
- explicitely tell if the op has side
- effects. Currently we assume that if nb_oargs == 0
- or OPF_BB_END is set, the operation has side
- effects and cannot be removed */
- if (nb_oargs != 0 && !(def->flags & TCG_OPF_BB_END)) {
+ its outputs are dead. We assume that nb_oargs == 0
+ implies side effects */
+ if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
for(i = 0; i < nb_oargs; i++) {
arg = args[i];
if (!dead_temps[arg])
ts = &s->temps[temp];
s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
- abort();
+ tcg_abort();
ts->mem_offset = s->current_frame_offset;
ts->mem_reg = s->frame_reg;
ts->mem_allocated = 1;
}
}
assert(ts->val_type == TEMP_VAL_REG);
- if ((arg_ct->ct & TCG_CT_IALIAS) &&
- !IS_DEAD_IARG(i - nb_oargs)) {
- /* if the input is aliased to an output and if it is
- not dead after the instruction, we must allocate
- a new register and move it */
- goto allocate_in_reg;
+ if (arg_ct->ct & TCG_CT_IALIAS) {
+ if (ts->fixed_reg) {
+ /* if fixed register, we must allocate a new register
+ if the alias is not the same register */
+ if (arg != args[arg_ct->alias_index])
+ goto allocate_in_reg;
+ } else {
+ /* if the input is aliased to an output and if it is
+ not dead after the instruction, we must allocate
+ a new register and move it */
+ if (!IS_DEAD_IARG(i - nb_oargs))
+ goto allocate_in_reg;
+ }
}
reg = ts->reg;
if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
arg_ct = &def->args_ct[i];
ts = &s->temps[arg];
if (arg_ct->ct & TCG_CT_ALIAS) {
- reg = new_args[arg_ct->ct & ~TCG_CT_ALIAS];
+ reg = new_args[arg_ct->alias_index];
} else {
/* if fixed register, we try to use it */
reg = ts->reg;
case INDEX_op_nopn:
args += args[0];
goto next;
+ case INDEX_op_discard:
+ {
+ TCGTemp *ts;
+ ts = &s->temps[args[0]];
+ /* mark the temporary as dead */
+ if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
+ if (ts->val_type == TEMP_VAL_REG)
+ s->reg_to_temp[ts->reg] = -1;
+ ts->val_type = TEMP_VAL_DEAD;
+ }
+ }
+ break;
case INDEX_op_macro_goto:
macro_op_index = op_index; /* only used for exceptions */
op_index = args[0] - 1;