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

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.

Acked-by: default avatarClaudio Fontana <claudio.fontana@huawei.com>
Tested-by: default avatarClaudio Fontana <claudio.fontana@huawei.com>
Cc: Andrzej Zaborowski <balrogg@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Stefan Weil <sw@weilnetz.de>
Reviewed-by: default avatarBastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 42a268c2
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -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);
}

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) {
        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);
    } else {
        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,
                           TCGArg b, bool b_const, int label)
                           TCGArg b, bool b_const, TCGLabel *l)
{
    TCGLabel *l = &s->labels[label];
    intptr_t offset;
    bool need_cmp;

@@ -864,7 +861,7 @@ static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
    }

    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;
    } else {
        offset = l->u.value_ptr - s->code_ptr;
@@ -1272,7 +1269,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
        break;

    case INDEX_op_br:
        tcg_out_goto_label(s, a0);
        tcg_out_goto_label(s, arg_label(a0));
        break;

    case INDEX_op_ld8u_i32:
@@ -1495,7 +1492,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
        a1 = (int32_t)a1;
        /* FALLTHRU */
    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(args[3]));
        break;

    case INDEX_op_setcond_i32:
+7 −7
Original line number Diff line number Diff line
@@ -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) {
        tcg_out_goto(s, cond, l->u.value_ptr);
    } 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);
    }
}
@@ -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);
        break;
    case INDEX_op_br:
        tcg_out_goto_label(s, COND_AL, args[0]);
        tcg_out_goto_label(s, COND_AL, arg_label(args[0]));
        break;

    case INDEX_op_ld8u_i32:
@@ -1821,7 +1819,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
    case INDEX_op_brcond_i32:
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
                       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(args[3]));
        break;
    case INDEX_op_brcond2_i32:
        /* 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]);
        tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
                        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(args[5]));
        break;
    case INDEX_op_setcond_i32:
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
+38 −38
Original line number Diff line number Diff line
@@ -853,10 +853,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
}

/* Use SMALL != 0 to force a short forward branch.  */
static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small)
{
    int32_t val, val1;
    TCGLabel *l = &s->labels[label_index];

    if (l->has_value) {
        val = tcg_pcrel_diff(s, l->u.value_ptr);
@@ -886,7 +885,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
        } else {
            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;
    } else {
        if (opc == -1) {
@@ -894,7 +893,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
        } else {
            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;
    }
}
@@ -916,19 +915,19 @@ static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,

static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
                             TCGArg arg1, TCGArg arg2, int const_arg2,
                             int label_index, int small)
                             TCGLabel *label, int small)
{
    tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small);
}

#if TCG_TARGET_REG_BITS == 64
static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
                             TCGArg arg1, TCGArg arg2, int const_arg2,
                             int label_index, int small)
                             TCGLabel *label, int small)
{
    tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small);
}
#else
/* XXX: we implement it at the target level to avoid having to
@@ -936,76 +935,77 @@ static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
                            const int *const_args, int small)
{
    int label_next = label_arg(gen_new_label());
    TCGLabel *label_next = gen_new_label();
    TCGLabel *label_this = arg_label(args[5]);

    switch(args[4]) {
    case TCG_COND_EQ:
        tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
                         label_next, 1);
        tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_NE:
        tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_LT:
        tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_LE:
        tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_GT:
        tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_GE:
        tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_LTU:
        tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_LEU:
        tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_GTU:
        tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    case TCG_COND_GEU:
        tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
                         args[5], small);
                         label_this, small);
        tcg_out_jxx(s, JCC_JNE, label_next, 1);
        tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
                         args[5], small);
                         label_this, small);
        break;
    default:
        tcg_abort();
@@ -1035,7 +1035,7 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
                             const int *const_args)
{
    TCGArg new_args[6];
    int label_true, label_over;
    TCGLabel *label_true, *label_over;

    memcpy(new_args, args+1, 5*sizeof(TCGArg));

@@ -1044,10 +1044,10 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
        || (!const_args[4] && args[0] == args[4])) {
        /* When the destination overlaps with one of the argument
           registers, don't do anything tricky.  */
        label_true = label_arg(gen_new_label());
        label_over = label_arg(gen_new_label());
        label_true = gen_new_label();
        label_over = gen_new_label();

        new_args[5] = label_true;
        new_args[5] = label_arg(label_true);
        tcg_out_brcond2(s, new_args, const_args+1, 1);

        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
@@ -1063,9 +1063,9 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,

        tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);

        label_over = label_arg(gen_new_label());
        label_over = gen_new_label();
        new_args[4] = tcg_invert_cond(new_args[4]);
        new_args[5] = label_over;
        new_args[5] = label_arg(label_over);
        tcg_out_brcond2(s, new_args, const_args+1, 1);

        tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
@@ -1082,7 +1082,7 @@ static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
    if (have_cmov) {
        tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
    } else {
        int over = label_arg(gen_new_label());
        TCGLabel *over = gen_new_label();
        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_label(s, over, s->code_ptr);
@@ -1748,7 +1748,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
        s->tb_next_offset[args[0]] = tcg_current_code_size(s);
        break;
    case INDEX_op_br:
        tcg_out_jxx(s, JCC_JMP, args[0], 0);
        tcg_out_jxx(s, JCC_JMP, arg_label(args[0]), 0);
        break;
    OP_32_64(ld8u):
        /* Note that we can ignore REXW for the zero-extend to 64-bit.  */
@@ -1909,7 +1909,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,

    case INDEX_op_brcond_i32:
        tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
                         args[3], 0);
                         arg_label(args[3]), 0);
        break;
    case INDEX_op_setcond_i32:
        tcg_out_setcond32(s, args[3], args[0], args[1],
@@ -2017,7 +2017,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,

    case INDEX_op_brcond_i64:
        tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
                         args[3], 0);
                         arg_label(args[3]), 0);
        break;
    case INDEX_op_setcond_i64:
        tcg_out_setcond64(s, args[3], args[0], args[1],
+7 −9
Original line number Diff line number Diff line
@@ -827,9 +827,8 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
                   tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, reg, arg));
}

static void tcg_out_br(TCGContext *s, int label_index)
static void tcg_out_br(TCGContext *s, TCGLabel *l)
{
    TCGLabel *l = &s->labels[label_index];
    uint64_t imm;

    /* We pay attention here to not modify the branch target by reading
@@ -839,7 +838,7 @@ static void tcg_out_br(TCGContext *s, int label_index)
        imm = l->u.value_ptr -  s->code_ptr;
    } else {
        imm = get_reloc_pcrel21b_slot2(s->code_ptr);
        tcg_out_reloc(s, s->code_ptr, R_IA64_PCREL21B, label_index, 0);
        tcg_out_reloc(s, s->code_ptr, R_IA64_PCREL21B, l, 0);
    }

    tcg_out_bundle(s, mmB,
@@ -1424,9 +1423,8 @@ static inline uint64_t tcg_opc_cmp_a(int qp, TCGCond cond, TCGArg arg1,
}

static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
                                  TCGReg arg2, int label_index, int cmp4)
                                  TCGReg arg2, TCGLabel *l, int cmp4)
{
    TCGLabel *l = &s->labels[label_index];
    uint64_t imm;

    /* We pay attention here to not modify the branch target by reading
@@ -1436,7 +1434,7 @@ static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
        imm = l->u.value_ptr - s->code_ptr;
    } else {
        imm = get_reloc_pcrel21b_slot2(s->code_ptr);
        tcg_out_reloc(s, s->code_ptr, R_IA64_PCREL21B, label_index, 0);
        tcg_out_reloc(s, s->code_ptr, R_IA64_PCREL21B, l, 0);
    }

    tcg_out_bundle(s, miB,
@@ -1990,7 +1988,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
        tcg_out_exit_tb(s, args[0]);
        break;
    case INDEX_op_br:
        tcg_out_br(s, args[0]);
        tcg_out_br(s, arg_label(args[0]));
        break;
    case INDEX_op_goto_tb:
        tcg_out_goto_tb(s, args[0]);
@@ -2172,10 +2170,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
        break;

    case INDEX_op_brcond_i32:
        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 1);
        tcg_out_brcond(s, args[2], args[0], args[1], arg_label(args[3]), 1);
        break;
    case INDEX_op_brcond_i64:
        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 0);
        tcg_out_brcond(s, args[2], args[0], args[1], arg_label(args[3]), 0);
        break;
    case INDEX_op_setcond_i32:
        tcg_out_setcond(s, args[3], args[0], args[1], args[2], 1);
+8 −9
Original line number Diff line number Diff line
@@ -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,
                           TCGReg arg2, int label_index)
                           TCGReg arg2, TCGLabel *l)
{
    static const MIPSInsn b_zero[16] = {
        [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,
    };

    TCGLabel *l;
    MIPSInsn s_opc = OPC_SLTU;
    MIPSInsn b_opc;
    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);
    l = &s->labels[label_index];
    if (l->has_value) {
        reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
    } 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);
}
@@ -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,
                            TCGReg bl, TCGReg bh, int label_index)
                            TCGReg bl, TCGReg bh, TCGLabel *l)
{
    TCGCond b_cond = TCG_COND_NE;
    TCGReg tmp = TCG_TMP1;
@@ -790,7 +788,7 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
        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,
@@ -1367,7 +1365,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
        s->tb_next_offset[a0] = tcg_current_code_size(s);
        break;
    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(a0));
        break;

    case INDEX_op_ld8u_i32:
@@ -1527,10 +1526,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
        break;

    case INDEX_op_brcond_i32:
        tcg_out_brcond(s, a2, a0, a1, args[3]);
        tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
        break;
    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(args[5]));
        break;

    case INDEX_op_movcond_i32:
Loading