aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2017-10-25 07:14:20 -0700
committerRichard Henderson <richard.henderson@linaro.org>2017-11-03 09:33:45 +0100
commit5b38ee31616d1532c3c3a6dc644a9160d608ed2f (patch)
tree04745665710338a2aa13f11546f32e7e7dadda28
parent094611b426b3b532a3ec72256cb4e958149269d3 (diff)
tcg: Allow constant pool entries in the prologue
Both ARMv6 and AArch64 currently may drop complex guest_base values into the constant pool. But generic code wasn't expecting that, and the pool is not emitted. Correct that. Tested-by: Emilio G. Cota <cota@braap.org> Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com> Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--tcg/tcg.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 683ff4abb7..c22f1c4441 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -771,12 +771,32 @@ void tcg_prologue_init(TCGContext *s)
/* Put the prologue at the beginning of code_gen_buffer. */
buf0 = s->code_gen_buffer;
+ total_size = s->code_gen_buffer_size;
s->code_ptr = buf0;
s->code_buf = buf0;
+ s->data_gen_ptr = NULL;
s->code_gen_prologue = buf0;
+ /* Compute a high-water mark, at which we voluntarily flush the buffer
+ and start over. The size here is arbitrary, significantly larger
+ than we expect the code generation for any one opcode to require. */
+ s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
+
+#ifdef TCG_TARGET_NEED_POOL_LABELS
+ s->pool_labels = NULL;
+#endif
+
/* Generate the prologue. */
tcg_target_qemu_prologue(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);
+ }
+#endif
+
buf1 = s->code_ptr;
flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
@@ -785,21 +805,36 @@ void tcg_prologue_init(TCGContext *s)
s->code_gen_ptr = buf1;
s->code_gen_buffer = buf1;
s->code_buf = buf1;
- total_size = s->code_gen_buffer_size - prologue_size;
+ total_size -= prologue_size;
s->code_gen_buffer_size = total_size;
- /* Compute a high-water mark, at which we voluntarily flush the buffer
- and start over. The size here is arbitrary, significantly larger
- than we expect the code generation for any one opcode to require. */
- s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
-
tcg_register_jit(s->code_gen_buffer, total_size);
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
qemu_log_lock();
qemu_log("PROLOGUE: [size=%zu]\n", prologue_size);
- log_disas(buf0, prologue_size);
+ if (s->data_gen_ptr) {
+ size_t code_size = s->data_gen_ptr - buf0;
+ size_t data_size = prologue_size - code_size;
+ size_t i;
+
+ log_disas(buf0, code_size);
+
+ for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
+ if (sizeof(tcg_target_ulong) == 8) {
+ qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
+ (uintptr_t)s->data_gen_ptr + i,
+ *(uint64_t *)(s->data_gen_ptr + i));
+ } else {
+ qemu_log("0x%08" PRIxPTR ": .long 0x%08x\n",
+ (uintptr_t)s->data_gen_ptr + i,
+ *(uint32_t *)(s->data_gen_ptr + i));
+ }
+ }
+ } else {
+ log_disas(buf0, prologue_size);
+ }
qemu_log("\n");
qemu_log_flush();
qemu_log_unlock();