diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-04-28 11:43:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-04-28 11:43:10 +0100 |
commit | e0fb2c3d89aa77057ac4aa073e01f4ca484449b0 (patch) | |
tree | f28672f770bfe0b95165c10cad34dbaf214fdbea /tcg/tcg.c | |
parent | 9ec34ecc97bcd5df04b0f67a774d79ffcd6b0a11 (diff) | |
parent | ef5dae6805cce7b59d129d801bdc5db71bcbd60d (diff) |
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190426' into staging
Add tcg_gen_extract2_*.
Deal with overflow of TranslationBlocks.
Respect access_type in io_readx.
# gpg: Signature made Fri 26 Apr 2019 18:17:01 BST
# gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg: issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* remotes/rth/tags/pull-tcg-20190426:
cputlb: Fix io_readx() to respect the access_type
tcg/arm: Restrict constant pool displacement to 12 bits
tcg/ppc: Allow the constant pool to overflow at 32k
tcg: Restart TB generation after out-of-line ldst overflow
tcg: Restart TB generation after constant pool overflow
tcg: Restart TB generation after relocation overflow
tcg: Restart after TB code generation overflow
tcg: Hoist max_insns computation to tb_gen_code
tcg/aarch64: Support INDEX_op_extract2_{i32,i64}
tcg/arm: Support INDEX_op_extract2_i32
tcg/i386: Support INDEX_op_extract2_{i32,i64}
tcg: Use extract2 in tcg_gen_deposit_{i32,i64}
tcg: Use deposit and extract2 in tcg_gen_shifti_i64
tcg: Add INDEX_op_extract2_{i32,i64}
tcg: Implement tcg_gen_extract2_{i32,i64}
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r-- | tcg/tcg.c | 87 |
1 files changed, 47 insertions, 40 deletions
@@ -128,7 +128,7 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct); #ifdef TCG_TARGET_NEED_LDST_LABELS -static bool tcg_out_ldst_finalize(TCGContext *s); +static int tcg_out_ldst_finalize(TCGContext *s); #endif #define TCG_HIGHWATER 1024 @@ -263,37 +263,17 @@ static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p, static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type, TCGLabel *l, intptr_t addend) { - TCGRelocation *r; - - if (l->has_value) { - /* FIXME: This may break relocations on RISC targets that - modify instruction fields in place. The caller may not have - written the initial value. */ - bool ok = patch_reloc(code_ptr, type, l->u.value, addend); - tcg_debug_assert(ok); - } else { - /* add a new relocation entry */ - r = tcg_malloc(sizeof(TCGRelocation)); - r->type = type; - r->ptr = code_ptr; - r->addend = addend; - r->next = l->u.first_reloc; - l->u.first_reloc = r; - } + TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation)); + + r->type = type; + r->ptr = code_ptr; + r->addend = addend; + QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next); } static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr) { - intptr_t value = (intptr_t)ptr; - TCGRelocation *r; - tcg_debug_assert(!l->has_value); - - for (r = l->u.first_reloc; r != NULL; r = r->next) { - bool ok = patch_reloc(r->ptr, r->type, value, r->addend); - tcg_debug_assert(ok); - } - l->has_value = 1; l->u.value_ptr = ptr; } @@ -303,16 +283,32 @@ TCGLabel *gen_new_label(void) TCGContext *s = tcg_ctx; TCGLabel *l = tcg_malloc(sizeof(TCGLabel)); - *l = (TCGLabel){ - .id = s->nb_labels++ - }; -#ifdef CONFIG_DEBUG_TCG + memset(l, 0, sizeof(TCGLabel)); + l->id = s->nb_labels++; + QSIMPLEQ_INIT(&l->relocs); + QSIMPLEQ_INSERT_TAIL(&s->labels, l, next); -#endif return l; } +static bool tcg_resolve_relocs(TCGContext *s) +{ + TCGLabel *l; + + QSIMPLEQ_FOREACH(l, &s->labels, next) { + TCGRelocation *r; + uintptr_t value = l->u.value; + + QSIMPLEQ_FOREACH(r, &l->relocs, next) { + if (!patch_reloc(r->ptr, r->type, value, r->addend)) { + return false; + } + } + } + return true; +} + static void set_jmp_reset_offset(TCGContext *s, int which) { size_t off = tcg_current_code_size(s); @@ -1023,8 +1019,8 @@ void tcg_prologue_init(TCGContext *s) #ifdef TCG_TARGET_NEED_POOL_LABELS /* Allow the prologue to put e.g. guest_base into a pool entry. */ { - bool ok = tcg_out_pool_finalize(s); - tcg_debug_assert(ok); + int result = tcg_out_pool_finalize(s); + tcg_debug_assert(result == 0); } #endif @@ -1096,9 +1092,7 @@ void tcg_func_start(TCGContext *s) QTAILQ_INIT(&s->ops); QTAILQ_INIT(&s->free_ops); -#ifdef CONFIG_DEBUG_TCG QSIMPLEQ_INIT(&s->labels); -#endif } static inline TCGTemp *tcg_temp_alloc(TCGContext *s) @@ -1426,6 +1420,8 @@ bool tcg_op_supported(TCGOpcode op) return TCG_TARGET_HAS_extract_i32; case INDEX_op_sextract_i32: return TCG_TARGET_HAS_sextract_i32; + case INDEX_op_extract2_i32: + return TCG_TARGET_HAS_extract2_i32; case INDEX_op_add2_i32: return TCG_TARGET_HAS_add2_i32; case INDEX_op_sub2_i32: @@ -1523,6 +1519,8 @@ bool tcg_op_supported(TCGOpcode op) return TCG_TARGET_HAS_extract_i64; case INDEX_op_sextract_i64: return TCG_TARGET_HAS_sextract_i64; + case INDEX_op_extract2_i64: + return TCG_TARGET_HAS_extract2_i64; case INDEX_op_extrl_i64_i32: return TCG_TARGET_HAS_extrl_i64_i32; case INDEX_op_extrh_i64_i32: @@ -3992,21 +3990,30 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { return -1; } + /* Test for TB overflow, as seen by gen_insn_end_off. */ + if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) { + return -2; + } } tcg_debug_assert(num_insns >= 0); s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); /* Generate TB finalization at the end of block */ #ifdef TCG_TARGET_NEED_LDST_LABELS - if (!tcg_out_ldst_finalize(s)) { - return -1; + i = tcg_out_ldst_finalize(s); + if (i < 0) { + return i; } #endif #ifdef TCG_TARGET_NEED_POOL_LABELS - if (!tcg_out_pool_finalize(s)) { - return -1; + i = tcg_out_pool_finalize(s); + if (i < 0) { + return i; } #endif + if (!tcg_resolve_relocs(s)) { + return -2; + } /* flush instruction cache */ flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); |