@@ -191,9 +191,10 @@ DEF(mulsh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulsh_i64))
/* QEMU specific */
DEF(insn_start, 0, 0, TLADDR_ARGS * TARGET_INSN_START_WORDS,
TCG_OPF_NOT_PRESENT)
-DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END)
-DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
+DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(goto_ptr, 0, 1, 0,
+ TCG_OPF_BB_EXIT | TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr))
DEF(qemu_ld_i32, 1, TLADDR_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
@@ -1030,20 +1030,22 @@ typedef struct TCGArgConstraint {
/* Bits for TCGOpDef->flags, 8 bits available. */
enum {
+ /* Instruction exits the translation block. */
+ TCG_OPF_BB_EXIT = 0x01,
/* Instruction defines the end of a basic block. */
- TCG_OPF_BB_END = 0x01,
+ TCG_OPF_BB_END = 0x02,
/* Instruction clobbers call registers and potentially update globals. */
- TCG_OPF_CALL_CLOBBER = 0x02,
+ TCG_OPF_CALL_CLOBBER = 0x04,
/* Instruction has side effects: it cannot be removed if its outputs
are not used, and might trigger exceptions. */
- TCG_OPF_SIDE_EFFECTS = 0x04,
+ TCG_OPF_SIDE_EFFECTS = 0x08,
/* Instruction operands are 64-bits (otherwise 32-bits). */
- TCG_OPF_64BIT = 0x08,
+ TCG_OPF_64BIT = 0x10,
/* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemened by the host. */
- TCG_OPF_NOT_PRESENT = 0x10,
+ TCG_OPF_NOT_PRESENT = 0x20,
/* Instruction operands are vectors. */
- TCG_OPF_VECTOR = 0x20,
+ TCG_OPF_VECTOR = 0x40,
};
typedef struct TCGOpDef {
@@ -2424,6 +2424,7 @@ static void liveness_pass_1(TCGContext *s)
int nb_temps = s->nb_temps;
TCGOp *op, *op_prev;
+ /* ??? Should be redundant with the exit_tb that ends the TB. */
la_func_end(s, nb_globals, nb_temps);
QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, TCGOpHead, link, op_prev) {
@@ -2612,7 +2613,9 @@ static void liveness_pass_1(TCGContext *s)
}
/* if end of basic block, update */
- if (def->flags & TCG_OPF_BB_END) {
+ if (def->flags & TCG_OPF_BB_EXIT) {
+ la_func_end(s, nb_globals, nb_temps);
+ } else if (def->flags & TCG_OPF_BB_END) {
la_bb_end(s, nb_globals, nb_temps);
} else if (def->flags & TCG_OPF_SIDE_EFFECTS) {
la_global_sync(s, nb_globals);