Commit aeee05f5 authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg: Restart TB generation after out-of-line ldst overflow



This is part c of relocation overflow handling.

Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent 1768987b
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -1395,14 +1395,15 @@ static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target)
    tcg_out_insn(s, 3406, ADR, rd, offset);
}

static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);
    TCGMemOp size = opc & MO_SIZE;

    bool ok = reloc_pc19(lb->label_ptr[0], s->code_ptr);
    tcg_debug_assert(ok);
    if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
    tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
@@ -1416,16 +1417,18 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
    }

    tcg_out_goto(s, lb->raddr);
    return true;
}

static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);
    TCGMemOp size = opc & MO_SIZE;

    bool ok = reloc_pc19(lb->label_ptr[0], s->code_ptr);
    tcg_debug_assert(ok);
    if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
    tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
@@ -1434,6 +1437,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
    tcg_out_adr(s, TCG_REG_X4, lb->raddr);
    tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
    tcg_out_goto(s, lb->raddr);
    return true;
}

static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
+10 −6
Original line number Diff line number Diff line
@@ -1372,15 +1372,16 @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
    label->label_ptr[0] = label_ptr;
}

static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGReg argreg, datalo, datahi;
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);
    void *func;

    bool ok = reloc_pc24(lb->label_ptr[0], s->code_ptr);
    tcg_debug_assert(ok);
    if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    argreg = tcg_out_arg_reg32(s, TCG_REG_R0, TCG_AREG0);
    if (TARGET_LONG_BITS == 64) {
@@ -1432,16 +1433,18 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
    }

    tcg_out_goto(s, COND_AL, lb->raddr);
    return true;
}

static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGReg argreg, datalo, datahi;
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);

    bool ok = reloc_pc24(lb->label_ptr[0], s->code_ptr);
    tcg_debug_assert(ok);
    if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    argreg = TCG_REG_R0;
    argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
@@ -1474,6 +1477,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)

    /* Tail-call to the helper, which will return to the fast path.  */
    tcg_out_goto(s, COND_AL, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
    return true;
}
#endif /* SOFTMMU */

+4 −2
Original line number Diff line number Diff line
@@ -1730,7 +1730,7 @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, bool is_64,
/*
 * Generate code for the slow path for a load at the end of block
 */
static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
    TCGMemOpIdx oi = l->oi;
    TCGMemOp opc = get_memop(oi);
@@ -1809,12 +1809,13 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)

    /* Jump to the code corresponding to next IR of qemu_st */
    tcg_out_jmp(s, l->raddr);
    return true;
}

/*
 * Generate code for the slow path for a store at the end of block
 */
static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
    TCGMemOpIdx oi = l->oi;
    TCGMemOp opc = get_memop(oi);
@@ -1877,6 +1878,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
    /* "Tail call" to the helper, with the return address back inline.  */
    tcg_out_push(s, retaddr);
    tcg_out_jmp(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
    return true;
}
#elif TCG_TARGET_REG_BITS == 32
# define x86_guest_base_seg     0
+4 −2
Original line number Diff line number Diff line
@@ -1338,7 +1338,7 @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
    }
}

static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
    TCGMemOpIdx oi = l->oi;
    TCGMemOp opc = get_memop(oi);
@@ -1385,9 +1385,10 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
    } else {
        tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO);
    }
    return true;
}

static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
    TCGMemOpIdx oi = l->oi;
    TCGMemOp opc = get_memop(oi);
@@ -1435,6 +1436,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
    tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
    /* delay slot */
    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
    return true;
}
#endif

+10 −4
Original line number Diff line number Diff line
@@ -1653,13 +1653,15 @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
    label->label_ptr[0] = lptr;
}

static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);
    TCGReg hi, lo, arg = TCG_REG_R3;

    **lb->label_ptr |= reloc_pc14_val(*lb->label_ptr, s->code_ptr);
    if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);

@@ -1695,16 +1697,19 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
    }

    tcg_out_b(s, 0, lb->raddr);
    return true;
}

static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
    TCGMemOpIdx oi = lb->oi;
    TCGMemOp opc = get_memop(oi);
    TCGMemOp s_bits = opc & MO_SIZE;
    TCGReg hi, lo, arg = TCG_REG_R3;

    **lb->label_ptr |= reloc_pc14_val(*lb->label_ptr, s->code_ptr);
    if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
        return false;
    }

    tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);

@@ -1753,6 +1758,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
    tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);

    tcg_out_b(s, 0, lb->raddr);
    return true;
}
#endif /* SOFTMMU */

Loading