diff options
author | Richard Henderson <rth@twiddle.net> | 2015-02-13 12:51:55 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2015-03-13 12:28:18 -0700 |
commit | 42a268c241183877192c376d03bd9b6d527407c7 (patch) | |
tree | e41a70d15c0a61d4618b08b889ab9dd56df9c35c /tcg | |
parent | 3f626793a2182061e3aa50a9e2ed7a322582a60f (diff) |
tcg: Change translator-side labels to a pointer
This is improved type checking for the translators -- it's no longer
possible to accidentally swap arguments to the branch functions.
Note that the code generating backends still manipulate labels as int.
With notable exceptions, the scope of the change is just a few lines
for each target, so it's not worth building extra machinery to do this
change in per-target increments.
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Cc: Anthony Green <green@moxielogic.com>
Cc: Jia Liu <proljc@gmail.com>
Cc: Alexander Graf <agraf@suse.de>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/i386/tcg-target.c | 12 | ||||
-rw-r--r-- | tcg/tcg-op.c | 25 | ||||
-rw-r--r-- | tcg/tcg-op.h | 19 | ||||
-rw-r--r-- | tcg/tcg.c | 5 | ||||
-rw-r--r-- | tcg/tcg.h | 30 |
5 files changed, 60 insertions, 31 deletions
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 4133dcf1a9..14628433af 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -936,8 +936,8 @@ 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_next = gen_new_label(); + int label_next = label_arg(gen_new_label()); + switch(args[4]) { case TCG_COND_EQ: tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2], @@ -1044,8 +1044,8 @@ 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 = gen_new_label(); - label_over = gen_new_label(); + label_true = label_arg(gen_new_label()); + label_over = label_arg(gen_new_label()); new_args[5] = label_true; tcg_out_brcond2(s, new_args, const_args+1, 1); @@ -1063,7 +1063,7 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args, tcg_out_movi(s, TCG_TYPE_I32, args[0], 0); - label_over = gen_new_label(); + label_over = label_arg(gen_new_label()); new_args[4] = tcg_invert_cond(new_args[4]); new_args[5] = label_over; tcg_out_brcond2(s, new_args, const_args+1, 1); @@ -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 = gen_new_label(); + int over = label_arg(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); diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index afa351dc70..6674bb4430 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -275,19 +275,19 @@ void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) } } -void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, int label) +void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l) { if (cond == TCG_COND_ALWAYS) { - tcg_gen_br(label); + tcg_gen_br(l); } else if (cond != TCG_COND_NEVER) { - tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label); + tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l)); } } -void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, int label) +void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l) { TCGv_i32 t0 = tcg_const_i32(arg2); - tcg_gen_brcond_i32(cond, arg1, t0, label); + tcg_gen_brcond_i32(cond, arg1, t0, l); tcg_temp_free_i32(t0); } @@ -1084,28 +1084,29 @@ void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) } } -void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label) +void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l) { if (cond == TCG_COND_ALWAYS) { - tcg_gen_br(label); + tcg_gen_br(l); } else if (cond != TCG_COND_NEVER) { if (TCG_TARGET_REG_BITS == 32) { tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2), - TCGV_HIGH(arg2), cond, label); + TCGV_HIGH(arg2), cond, label_arg(l)); } else { - tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label); + tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, + label_arg(l)); } } } -void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, int label) +void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l) { if (cond == TCG_COND_ALWAYS) { - tcg_gen_br(label); + tcg_gen_br(l); } else if (cond != TCG_COND_NEVER) { TCGv_i64 t0 = tcg_const_i64(arg2); - tcg_gen_brcond_i64(cond, arg1, t0, label); + tcg_gen_brcond_i64(cond, arg1, t0, l); tcg_temp_free_i64(t0); } } diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 96adf9af6a..d1d763f6ff 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -251,19 +251,16 @@ static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, /* Generic ops. */ -int gen_new_label(void); - -static inline void gen_set_label(int n) +static inline void gen_set_label(TCGLabel *l) { - tcg_gen_op1(&tcg_ctx, INDEX_op_set_label, n); + tcg_gen_op1(&tcg_ctx, INDEX_op_set_label, label_arg(l)); } -static inline void tcg_gen_br(int label) +static inline void tcg_gen_br(TCGLabel *l) { - tcg_gen_op1(&tcg_ctx, INDEX_op_br, label); + tcg_gen_op1(&tcg_ctx, INDEX_op_br, label_arg(l)); } - /* Helper calls. */ /* 32 bit ops */ @@ -293,8 +290,8 @@ void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2); void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, unsigned int ofs, unsigned int len); -void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, int label); -void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, int label); +void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *); +void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *); void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, @@ -469,8 +466,8 @@ void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2); void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, unsigned int ofs, unsigned int len); -void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label); -void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, int label); +void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *); +void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *); void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, @@ -246,7 +246,7 @@ static void tcg_out_label(TCGContext *s, int label_index, tcg_insn_unit *ptr) l->u.value_ptr = ptr; } -int gen_new_label(void) +TCGLabel *gen_new_label(void) { TCGContext *s = &tcg_ctx; int idx; @@ -258,7 +258,8 @@ int gen_new_label(void) l = &s->labels[idx]; l->has_value = 0; l->u.first_reloc = NULL; - return idx; + + return l; } #include "tcg-target.c" @@ -755,6 +755,36 @@ TCGv_i64 tcg_const_i64(int64_t val); TCGv_i32 tcg_const_local_i32(int32_t val); TCGv_i64 tcg_const_local_i64(int64_t val); +TCGLabel *gen_new_label(void); + +/** + * label_arg + * @l: label + * + * Encode a label for storage in the TCG opcode stream. + */ + +static inline TCGArg label_arg(TCGLabel *l) +{ + ptrdiff_t idx = l - tcg_ctx.labels; + tcg_debug_assert(idx >= 0 && idx < tcg_ctx.nb_labels); + return idx; +} + +/** + * arg_label + * @i: value + * + * The opposite of label_arg. Retrieve a label from the + * encoding of the TCG opcode stream. + */ + +static inline TCGLabel *arg_label(TCGArg idx) +{ + tcg_debug_assert(idx < tcg_ctx.nb_labels); + return &tcg_ctx.labels[idx]; +} + /** * tcg_ptr_byte_diff * @a, @b: addresses to be differenced |