Merge tag 'pull-testing-next-010323-1' of https://gitlab.com/stsquad/qemu into staging
testing updates:
- ensure socat available for tests
- skip socat tests for MacOS
- properly clean up fifos after use
- make fp-test less chatty
- store test artefacts on Cirrus
- control custom runners with QEMU_CI knobs
- disable benchmark runs under tsan build
- update ubuntu 2004 to 2204
- skip nios2 kernel replay test
- add tuxrun baselines to avocado
- binary build of tricore tools
- export test results on cross builds
- improve windows builds
- ensure we properly print TAP headers
- migrate away from docker.py for building containers
- be more efficient in our handling of build artefacts between stages
- enable ztsd in containers so we can run tux_baselines
- disable heavyweight PPC64 Boot Linux test in CI
# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmP/SmUACgkQ+9DbCVqe
# KkQgSQgAmVrXEL+1/L7JNka/xDumZ+t39oxAAcY22WfV0dNIC85WQ/02A3+uMZmt
# pbNXq7PPvZ1YE4ygjqwHu5WabEA1lmcdAoyg8/ACwnQMDyQ9RZGxceNO3UUsaoNx
# b3U/hsOS1ggo5lzzfamsRj2xbxthtUx2MJZQe96NTWSut1ibcHLYyaOqxCY6Q5zJ
# ZONOHOd3NLlrb+omLONLp9J+100Dt/x1UHsW5daSqRKaoDucO6w/So6YxGOshn90
# tJIJ/vKTtYBZBfF5JYoJ7A/m9Ia/YjcTVLxbXpMI6Bvw0P9PSIAZuvgbKfxfIAnf
# EHqZo1B71aH74vFTttK9Q1rnf9/9Cg==
# =grRh
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 01 Mar 2023 12:51:49 GMT
# gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44
* tag 'pull-testing-next-010323-1' of https://gitlab.com/stsquad/qemu: (24 commits)
tests/avocado: disable BootLinuxPPC64 test in CI
tests/docker: add zstdtools to the images
gitlab: move the majority of artefact handling to a template
tests/docker: use direct RUNC call to run test jobs
tests/docker: use direct RUNC call to build containers
tests/docker: add USER stanzas to non-lci images
tests/lcitool: append user setting stanza to dockerfiles
configure: expose the direct container command
tests: Ensure TAP version is printed before other messages
gitlab: Use plain docker in container-template.yml
tests/dockerfiles: unify debian-toolchain references
cirrus.yml: Improve the windows_msys2_task
tests: ensure we export job results for some cross builds
tests/docker: Use binaries for debian-tricore-cross
tests: add tuxrun baseline test to avocado
tests: skip the nios2 replay_kernel test
testing: update ubuntu2004 to ubuntu2204
tests: don't run benchmarks for the tsan build
gitlab: extend custom runners with base_job_template
gitlab-ci: Use artifacts instead of dumping logs in the Cirrus-CI jobs
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index c1b0576..96af23d 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -25,7 +25,7 @@
{
}
-int probe_access_flags(CPUArchState *env, target_ulong addr,
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t retaddr)
{
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index ef557e5..56aaf58 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -183,7 +183,7 @@
const TranslationBlock *tb = p;
const struct tb_desc *desc = d;
- if ((TARGET_TB_PCREL || tb_pc(tb) == desc->pc) &&
+ if ((tb_cflags(tb) & CF_PCREL || tb->pc == desc->pc) &&
tb_page_addr0(tb) == desc->page_addr0 &&
tb->cs_base == desc->cs_base &&
tb->flags == desc->flags &&
@@ -235,7 +235,7 @@
return NULL;
}
desc.page_addr0 = phys_pc;
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : pc),
+ h = tb_hash_func(phys_pc, (cflags & CF_PCREL ? 0 : pc),
flags, cflags, *cpu->trace_dstate);
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
}
@@ -254,21 +254,46 @@
hash = tb_jmp_cache_hash_func(pc);
jc = cpu->tb_jmp_cache;
- tb = tb_jmp_cache_get_tb(jc, hash);
- if (likely(tb &&
- tb_jmp_cache_get_pc(jc, hash, tb) == pc &&
- tb->cs_base == cs_base &&
- tb->flags == flags &&
- tb->trace_vcpu_dstate == *cpu->trace_dstate &&
- tb_cflags(tb) == cflags)) {
- return tb;
+ if (cflags & CF_PCREL) {
+ /* Use acquire to ensure current load of pc from jc. */
+ tb = qatomic_load_acquire(&jc->array[hash].tb);
+
+ if (likely(tb &&
+ jc->array[hash].pc == pc &&
+ tb->cs_base == cs_base &&
+ tb->flags == flags &&
+ tb->trace_vcpu_dstate == *cpu->trace_dstate &&
+ tb_cflags(tb) == cflags)) {
+ return tb;
+ }
+ tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
+ if (tb == NULL) {
+ return NULL;
+ }
+ jc->array[hash].pc = pc;
+ /* Use store_release on tb to ensure pc is written first. */
+ qatomic_store_release(&jc->array[hash].tb, tb);
+ } else {
+ /* Use rcu_read to ensure current load of pc from *tb. */
+ tb = qatomic_rcu_read(&jc->array[hash].tb);
+
+ if (likely(tb &&
+ tb->pc == pc &&
+ tb->cs_base == cs_base &&
+ tb->flags == flags &&
+ tb->trace_vcpu_dstate == *cpu->trace_dstate &&
+ tb_cflags(tb) == cflags)) {
+ return tb;
+ }
+ tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
+ if (tb == NULL) {
+ return NULL;
+ }
+ /* Use the pc value already stored in tb->pc. */
+ qatomic_set(&jc->array[hash].tb, tb);
}
- tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
- if (tb == NULL) {
- return NULL;
- }
- tb_jmp_cache_set(jc, hash, tb, pc);
+
return tb;
}
@@ -457,9 +482,9 @@
if (cc->tcg_ops->synchronize_from_tb) {
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
} else {
- assert(!TARGET_TB_PCREL);
+ tcg_debug_assert(!(tb_cflags(last_tb) & CF_PCREL));
assert(cc->set_pc);
- cc->set_pc(cpu, tb_pc(last_tb));
+ cc->set_pc(cpu, last_tb->pc);
}
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
target_ulong pc = log_pc(cpu, last_tb);
@@ -957,7 +982,8 @@
* for the fast lookup
*/
h = tb_jmp_cache_hash_func(pc);
- tb_jmp_cache_set(cpu->tb_jmp_cache, h, tb, pc);
+ /* Use the pc value already stored in tb->pc. */
+ qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
}
#ifndef CONFIG_USER_ONLY
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 4812d83..008ae7a 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1589,12 +1589,12 @@
return flags;
}
-int probe_access_full(CPUArchState *env, target_ulong addr,
+int probe_access_full(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, CPUTLBEntryFull **pfull,
uintptr_t retaddr)
{
- int flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
+ int flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
nonfault, phost, pfull, retaddr);
/* Handle clean RAM pages. */
@@ -1606,14 +1606,25 @@
return flags;
}
-int probe_access_flags(CPUArchState *env, target_ulong addr,
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t retaddr)
{
CPUTLBEntryFull *full;
+ int flags;
- return probe_access_full(env, addr, access_type, mmu_idx,
- nonfault, phost, &full, retaddr);
+ g_assert(-(addr | TARGET_PAGE_MASK) >= size);
+
+ flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
+ nonfault, phost, &full, retaddr);
+
+ /* Handle clean RAM pages. */
+ if (unlikely(flags & TLB_NOTDIRTY)) {
+ notdirty_write(env_cpu(env), addr, 1, full, retaddr);
+ flags &= ~TLB_NOTDIRTY;
+ }
+
+ return flags;
}
void *probe_access(CPUArchState *env, target_ulong addr, int size,
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index 130d7fd..96f198b 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -57,11 +57,11 @@
/* Return the current PC from CPU, which may be cached in TB. */
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
{
-#if TARGET_TB_PCREL
- return cpu->cc->get_pc(cpu);
-#else
- return tb_pc(tb);
-#endif
+ if (tb_cflags(tb) & CF_PCREL) {
+ return cpu->cc->get_pc(cpu);
+ } else {
+ return tb->pc;
+ }
}
extern int64_t max_delay;
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
index ae19f6e..65e35ea 100644
--- a/accel/tcg/perf.c
+++ b/accel/tcg/perf.c
@@ -328,7 +328,7 @@
for (insn = 0; insn < tb->icount; insn++) {
/* FIXME: This replicates the restore_state_to_opc() logic. */
q[insn].address = tcg_ctx->gen_insn_data[insn][0];
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(tb) & CF_PCREL) {
q[insn].address |= (guest_pc & TARGET_PAGE_MASK);
} else {
#if defined(TARGET_I386)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 17a686b..c42a436 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -93,11 +93,13 @@
static void do_gen_mem_cb(TCGv vaddr, uint32_t info)
{
- TCGv_i32 cpu_index = tcg_temp_new_i32();
- TCGv_i32 meminfo = tcg_const_i32(info);
- TCGv_i64 vaddr64 = tcg_temp_new_i64();
- TCGv_ptr udata = tcg_const_ptr(NULL);
+ TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
+ TCGv_i32 meminfo = tcg_temp_ebb_new_i32();
+ TCGv_i64 vaddr64 = tcg_temp_ebb_new_i64();
+ TCGv_ptr udata = tcg_temp_ebb_new_ptr();
+ tcg_gen_movi_i32(meminfo, info);
+ tcg_gen_movi_ptr(udata, 0);
tcg_gen_ld_i32(cpu_index, cpu_env,
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
tcg_gen_extu_tl_i64(vaddr64, vaddr);
@@ -112,9 +114,10 @@
static void gen_empty_udata_cb(void)
{
- TCGv_i32 cpu_index = tcg_temp_new_i32();
- TCGv_ptr udata = tcg_const_ptr(NULL); /* will be overwritten later */
+ TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
+ TCGv_ptr udata = tcg_temp_ebb_new_ptr();
+ tcg_gen_movi_ptr(udata, 0);
tcg_gen_ld_i32(cpu_index, cpu_env,
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
gen_helper_plugin_vcpu_udata_cb(cpu_index, udata);
@@ -129,9 +132,10 @@
*/
static void gen_empty_inline_cb(void)
{
- TCGv_i64 val = tcg_temp_new_i64();
- TCGv_ptr ptr = tcg_const_ptr(NULL); /* overwritten later */
+ TCGv_i64 val = tcg_temp_ebb_new_i64();
+ TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
+ tcg_gen_movi_ptr(ptr, 0);
tcg_gen_ld_i64(val, ptr, 0);
/* pass an immediate != 0 so that it doesn't get optimized away */
tcg_gen_addi_i64(val, val, 0xdeadface);
@@ -151,9 +155,9 @@
*/
static void gen_empty_mem_helper(void)
{
- TCGv_ptr ptr;
+ TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
- ptr = tcg_const_ptr(NULL);
+ tcg_gen_movi_ptr(ptr, 0);
tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
offsetof(ArchCPU, env));
tcg_temp_free_ptr(ptr);
@@ -626,8 +630,6 @@
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
- TCGv_ptr ptr;
-
/*
* We could emit the clearing unconditionally and be done. However, this can
* be wasteful if for instance plugins don't track memory accesses, or if
@@ -640,10 +642,8 @@
if (!tcg_ctx->plugin_tb->mem_helper) {
return;
}
- ptr = tcg_const_ptr(NULL);
- tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
- offsetof(ArchCPU, env));
- tcg_temp_free_ptr(ptr);
+ tcg_gen_st_ptr(tcg_constant_ptr(NULL), cpu_env,
+ offsetof(CPUState, plugin_mem_cbs) - offsetof(ArchCPU, env));
}
static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
index b3f6e78..bee87eb 100644
--- a/accel/tcg/tb-jmp-cache.h
+++ b/accel/tcg/tb-jmp-cache.h
@@ -14,53 +14,15 @@
/*
* Accessed in parallel; all accesses to 'tb' must be atomic.
- * For TARGET_TB_PCREL, accesses to 'pc' must be protected by
- * a load_acquire/store_release to 'tb'.
+ * For CF_PCREL, accesses to 'pc' must be protected by a
+ * load_acquire/store_release to 'tb'.
*/
struct CPUJumpCache {
struct rcu_head rcu;
struct {
TranslationBlock *tb;
-#if TARGET_TB_PCREL
target_ulong pc;
-#endif
} array[TB_JMP_CACHE_SIZE];
};
-static inline TranslationBlock *
-tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
-{
-#if TARGET_TB_PCREL
- /* Use acquire to ensure current load of pc from jc. */
- return qatomic_load_acquire(&jc->array[hash].tb);
-#else
- /* Use rcu_read to ensure current load of pc from *tb. */
- return qatomic_rcu_read(&jc->array[hash].tb);
-#endif
-}
-
-static inline target_ulong
-tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
-{
-#if TARGET_TB_PCREL
- return jc->array[hash].pc;
-#else
- return tb_pc(tb);
-#endif
-}
-
-static inline void
-tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
- TranslationBlock *tb, target_ulong pc)
-{
-#if TARGET_TB_PCREL
- jc->array[hash].pc = pc;
- /* Use store_release on tb to ensure pc is written first. */
- qatomic_store_release(&jc->array[hash].tb, tb);
-#else
- /* Use the pc value already stored in tb->pc. */
- qatomic_set(&jc->array[hash].tb, tb);
-#endif
-}
-
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index b3d6529..efefa08 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -44,7 +44,7 @@
const TranslationBlock *a = ap;
const TranslationBlock *b = bp;
- return ((TARGET_TB_PCREL || tb_pc(a) == tb_pc(b)) &&
+ return ((tb_cflags(a) & CF_PCREL || a->pc == b->pc) &&
a->cs_base == b->cs_base &&
a->flags == b->flags &&
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
@@ -847,13 +847,13 @@
{
CPUState *cpu;
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(tb) & CF_PCREL) {
/* A TB may be at any virtual address */
CPU_FOREACH(cpu) {
tcg_flush_jmp_cache(cpu);
}
} else {
- uint32_t h = tb_jmp_cache_hash_func(tb_pc(tb));
+ uint32_t h = tb_jmp_cache_hash_func(tb->pc);
CPU_FOREACH(cpu) {
CPUJumpCache *jc = cpu->tb_jmp_cache;
@@ -885,7 +885,7 @@
/* remove the TB from the hash list */
phys_pc = tb_page_addr0(tb);
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
+ h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, orig_cflags, tb->trace_vcpu_dstate);
if (!qht_remove(&tb_ctx.htable, tb, h)) {
return;
@@ -966,7 +966,7 @@
tb_record(tb, p, p2);
/* add in the hash table */
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
+ h = tb_hash_func(phys_pc, (tb->cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, tb->cflags, tb->trace_vcpu_dstate);
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 84f1293..4b5abc0 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -134,7 +134,7 @@
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
if (i == 0) {
- prev = (!TARGET_TB_PCREL && j == 0 ? tb_pc(tb) : 0);
+ prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0);
} else {
prev = tcg_ctx->gen_insn_data[i - 1][j];
}
@@ -169,8 +169,8 @@
}
memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
- if (!TARGET_TB_PCREL) {
- data[0] = tb_pc(tb);
+ if (!(tb_cflags(tb) & CF_PCREL)) {
+ data[0] = tb->pc;
}
/*
@@ -280,7 +280,7 @@
tcg_func_start(tcg_ctx);
tcg_ctx->cpu = env_cpu(env);
- gen_intermediate_code(env_cpu(env), tb, *max_insns, pc, host_pc);
+ gen_intermediate_code(env_cpu(env), tb, max_insns, pc, host_pc);
assert(tb->size != 0);
tcg_ctx->cpu = NULL;
*max_insns = tb->icount;
@@ -340,9 +340,9 @@
gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
-#if !TARGET_TB_PCREL
- tb->pc = pc;
-#endif
+ if (!(cflags & CF_PCREL)) {
+ tb->pc = pc;
+ }
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags;
@@ -407,8 +407,8 @@
tb->tc.size = gen_code_size;
/*
- * For TARGET_TB_PCREL, attribute all executions of the generated
- * code to its first mapping.
+ * For CF_PCREL, attribute all executions of the generated code
+ * to its first mapping.
*/
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 15d11fa..d0babfe 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -42,7 +42,7 @@
return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
}
-void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc,
const TranslatorOps *ops, DisasContextBase *db)
{
@@ -55,7 +55,7 @@
db->pc_next = pc;
db->is_jmp = DISAS_NEXT;
db->num_insns = 0;
- db->max_insns = max_insns;
+ db->max_insns = *max_insns;
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
db->host_addr[0] = host_pc;
db->host_addr[1] = NULL;
@@ -78,7 +78,7 @@
plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY);
while (true) {
- db->num_insns++;
+ *max_insns = ++db->num_insns;
ops->insn_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index ae67d84..7b37fd2 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -761,13 +761,14 @@
cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
}
-int probe_access_flags(CPUArchState *env, target_ulong addr,
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t ra)
{
int flags;
- flags = probe_access_internal(env, addr, 0, access_type, nonfault, ra);
+ g_assert(-(addr | TARGET_PAGE_MASK) >= size);
+ flags = probe_access_internal(env, addr, size, access_type, nonfault, ra);
*phost = flags ? NULL : g2h(env_cpu(env), addr);
return flags;
}
diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
index 1676ec1..df31706 100644
--- a/bsd-user/freebsd/os-sys.c
+++ b/bsd-user/freebsd/os-sys.c
@@ -21,6 +21,577 @@
#include "qemu.h"
#include "target_arch_sysarch.h"
+#include <sys/sysctl.h>
+
+/*
+ * Length for the fixed length types.
+ * 0 means variable length for strings and structures
+ * Compare with sys/kern_sysctl.c ctl_size
+ * Note: Not all types appear to be used in-tree.
+ */
+static const int guest_ctl_size[CTLTYPE + 1] = {
+ [CTLTYPE_INT] = sizeof(abi_int),
+ [CTLTYPE_UINT] = sizeof(abi_uint),
+ [CTLTYPE_LONG] = sizeof(abi_long),
+ [CTLTYPE_ULONG] = sizeof(abi_ulong),
+ [CTLTYPE_S8] = sizeof(int8_t),
+ [CTLTYPE_S16] = sizeof(int16_t),
+ [CTLTYPE_S32] = sizeof(int32_t),
+ [CTLTYPE_S64] = sizeof(int64_t),
+ [CTLTYPE_U8] = sizeof(uint8_t),
+ [CTLTYPE_U16] = sizeof(uint16_t),
+ [CTLTYPE_U32] = sizeof(uint32_t),
+ [CTLTYPE_U64] = sizeof(uint64_t),
+};
+
+static const int host_ctl_size[CTLTYPE + 1] = {
+ [CTLTYPE_INT] = sizeof(int),
+ [CTLTYPE_UINT] = sizeof(u_int),
+ [CTLTYPE_LONG] = sizeof(long),
+ [CTLTYPE_ULONG] = sizeof(u_long),
+ [CTLTYPE_S8] = sizeof(int8_t),
+ [CTLTYPE_S16] = sizeof(int16_t),
+ [CTLTYPE_S32] = sizeof(int32_t),
+ [CTLTYPE_S64] = sizeof(int64_t),
+ [CTLTYPE_U8] = sizeof(uint8_t),
+ [CTLTYPE_U16] = sizeof(uint16_t),
+ [CTLTYPE_U32] = sizeof(uint32_t),
+ [CTLTYPE_U64] = sizeof(uint64_t),
+};
+
+#ifdef TARGET_ABI32
+/*
+ * Limit the amount of available memory to be most of the 32-bit address
+ * space. 0x100c000 was arrived at through trial and error as a good
+ * definition of 'most'.
+ */
+static const abi_ulong guest_max_mem = UINT32_MAX - 0x100c000 + 1;
+
+static abi_ulong cap_memory(uint64_t mem)
+{
+ return MIN(guest_max_mem, mem);
+}
+#endif
+
+static abi_ulong scale_to_guest_pages(uint64_t pages)
+{
+ /* Scale pages from host to guest */
+ pages = muldiv64(pages, qemu_real_host_page_size(), TARGET_PAGE_SIZE);
+#ifdef TARGET_ABI32
+ /* cap pages if need be */
+ pages = MIN(pages, guest_max_mem / (abi_ulong)TARGET_PAGE_SIZE);
+#endif
+ return pages;
+}
+
+#ifdef TARGET_ABI32
+/* Used only for TARGET_ABI32 */
+static abi_long h2g_long_sat(long l)
+{
+ if (l > INT32_MAX) {
+ l = INT32_MAX;
+ } else if (l < INT32_MIN) {
+ l = INT32_MIN;
+ }
+ return l;
+}
+
+static abi_ulong h2g_ulong_sat(u_long ul)
+{
+ return MIN(ul, UINT32_MAX);
+}
+#endif
+
+/*
+ * placeholder until bsd-user downstream upstreams this with its thread support
+ */
+#define bsd_get_ncpu() 1
+
+/*
+ * This uses the undocumented oidfmt interface to find the kind of a requested
+ * sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt() (compare to
+ * src/sbin/sysctl/sysctl.c)
+ */
+static int oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
+{
+ int qoid[CTL_MAXNAME + 2];
+ uint8_t buf[BUFSIZ];
+ int i;
+ size_t j;
+
+ qoid[0] = CTL_SYSCTL;
+ qoid[1] = CTL_SYSCTL_OIDFMT;
+ memcpy(qoid + 2, oid, len * sizeof(int));
+
+ j = sizeof(buf);
+ i = sysctl(qoid, len + 2, buf, &j, 0, 0);
+ if (i) {
+ return i;
+ }
+
+ if (kind) {
+ *kind = *(uint32_t *)buf;
+ }
+
+ if (fmt) {
+ strcpy(fmt, (char *)(buf + sizeof(uint32_t)));
+ }
+ return 0;
+}
+
+/*
+ * Convert the old value from host to guest.
+ *
+ * For LONG and ULONG on ABI32, we need to 'down convert' the 8 byte quantities
+ * to 4 bytes. The caller setup a buffer in host memory to get this data from
+ * the kernel and pass it to us. We do the down conversion and adjust the length
+ * so the caller knows what to write as the returned length into the target when
+ * it copies the down converted values into the target.
+ *
+ * For normal integral types, we just need to byte swap. No size changes.
+ *
+ * For strings and node data, there's no conversion needed.
+ *
+ * For opaque data, per sysctl OID converts take care of it.
+ */
+static void h2g_old_sysctl(void *holdp, size_t *holdlen, uint32_t kind)
+{
+ size_t len;
+ int hlen, glen;
+ uint8_t *hp, *gp;
+
+ /*
+ * Although rare, we can have arrays of sysctl. Both sysctl_old_ddb in
+ * kern_sysctl.c and show_var in sbin/sysctl/sysctl.c have code that loops
+ * this way. *holdlen has been set by the kernel to the host's length.
+ * Only LONG and ULONG on ABI32 have different sizes: see below.
+ */
+ gp = hp = (uint8_t *)holdp;
+ len = 0;
+ hlen = host_ctl_size[kind & CTLTYPE];
+ glen = guest_ctl_size[kind & CTLTYPE];
+
+ /*
+ * hlen == 0 for CTLTYPE_STRING and CTLTYPE_NODE, which need no conversion
+ * as well as CTLTYPE_OPAQUE, which needs special converters.
+ */
+ if (hlen == 0) {
+ return;
+ }
+
+ while (len < *holdlen) {
+ if (hlen == glen) {
+ switch (hlen) {
+ case 1:
+ /* Nothing needed: no byteswapping and assigning in place */
+ break;
+ case 2:
+ *(uint16_t *)gp = tswap16(*(uint16_t *)hp);
+ break;
+ case 4:
+ *(uint32_t *)gp = tswap32(*(uint32_t *)hp);
+ break;
+ case 8:
+ *(uint64_t *)gp = tswap64(*(uint64_t *)hp);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+#ifdef TARGET_ABI32
+ /*
+ * Saturating assignment for the only two types that differ between
+ * 32-bit and 64-bit machines. All other integral types have the
+ * same, fixed size and will be converted w/o loss of precision
+ * in the above switch.
+ */
+ switch (kind & CTLTYPE) {
+ case CTLTYPE_LONG:
+ *(abi_long *)gp = tswap32(h2g_long_sat(*(long *)hp));
+ break;
+ case CTLTYPE_ULONG:
+ *(abi_ulong *)gp = tswap32(h2g_ulong_sat(*(u_long *)hp));
+ break;
+ default:
+ g_assert_not_reached();
+ }
+#else
+ g_assert_not_reached();
+#endif
+ }
+ gp += glen;
+ hp += hlen;
+ len += hlen;
+ }
+#ifdef TARGET_ABI32
+ if (hlen != glen) {
+ *holdlen = (*holdlen / hlen) * glen;
+ }
+#endif
+}
+
+/*
+ * Convert the undocmented name2oid sysctl data for the target.
+ */
+static inline void sysctl_name2oid(uint32_t *holdp, size_t holdlen)
+{
+ size_t i, num = holdlen / sizeof(uint32_t);
+
+ for (i = 0; i < num; i++) {
+ holdp[i] = tswap32(holdp[i]);
+ }
+}
+
+static inline void sysctl_oidfmt(uint32_t *holdp)
+{
+ /* byte swap the kind */
+ holdp[0] = tswap32(holdp[0]);
+}
+
+static abi_long do_freebsd_sysctl_oid(CPUArchState *env, int32_t *snamep,
+ int32_t namelen, void *holdp, size_t *holdlenp, void *hnewp,
+ size_t newlen)
+{
+ uint32_t kind = 0;
+ abi_long ret;
+ size_t holdlen, oldlen;
+#ifdef TARGET_ABI32
+ void *old_holdp;
+#endif
+
+ holdlen = oldlen = *holdlenp;
+ oidfmt(snamep, namelen, NULL, &kind);
+
+ /* Handle some arch/emulator dependent sysctl()'s here. */
+ switch (snamep[0]) {
+ case CTL_KERN:
+ switch (snamep[1]) {
+ case KERN_USRSTACK:
+ if (oldlen) {
+ (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+ }
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+ goto out;
+
+ case KERN_PS_STRINGS:
+ if (oldlen) {
+ (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS);
+ }
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+ goto out;
+
+ default:
+ break;
+ }
+ break;
+
+ case CTL_HW:
+ switch (snamep[1]) {
+ case HW_MACHINE:
+ holdlen = sizeof(TARGET_HW_MACHINE);
+ if (holdp) {
+ strlcpy(holdp, TARGET_HW_MACHINE, oldlen);
+ }
+ ret = 0;
+ goto out;
+
+ case HW_MACHINE_ARCH:
+ {
+ holdlen = sizeof(TARGET_HW_MACHINE_ARCH);
+ if (holdp) {
+ strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen);
+ }
+ ret = 0;
+ goto out;
+ }
+ case HW_NCPU:
+ if (oldlen) {
+ (*(abi_int *)holdp) = tswap32(bsd_get_ncpu());
+ }
+ holdlen = sizeof(int32_t);
+ ret = 0;
+ goto out;
+#if defined(TARGET_ARM)
+ case HW_FLOATINGPT:
+ if (oldlen) {
+ ARMCPU *cpu = env_archcpu(env);
+ *(abi_int *)holdp = cpu_isar_feature(aa32_vfp, cpu);
+ }
+ holdlen = sizeof(abi_int);
+ ret = 0;
+ goto out;
+#endif
+
+
+#ifdef TARGET_ABI32
+ case HW_PHYSMEM:
+ case HW_USERMEM:
+ case HW_REALMEM:
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+
+ if (oldlen) {
+ int mib[2] = {snamep[0], snamep[1]};
+ unsigned long lvalue;
+ size_t len = sizeof(lvalue);
+
+ if (sysctl(mib, 2, &lvalue, &len, NULL, 0) == -1) {
+ ret = -1;
+ } else {
+ lvalue = cap_memory(lvalue);
+ (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue);
+ }
+ }
+ goto out;
+#endif
+
+ default:
+ {
+ static int oid_hw_availpages;
+ static int oid_hw_pagesizes;
+
+ if (!oid_hw_availpages) {
+ int real_oid[CTL_MAXNAME + 2];
+ size_t len = sizeof(real_oid) / sizeof(int);
+
+ if (sysctlnametomib("hw.availpages", real_oid, &len) >= 0) {
+ oid_hw_availpages = real_oid[1];
+ }
+ }
+ if (!oid_hw_pagesizes) {
+ int real_oid[CTL_MAXNAME + 2];
+ size_t len = sizeof(real_oid) / sizeof(int);
+
+ if (sysctlnametomib("hw.pagesizes", real_oid, &len) >= 0) {
+ oid_hw_pagesizes = real_oid[1];
+ }
+ }
+
+ if (oid_hw_availpages && snamep[1] == oid_hw_availpages) {
+ long lvalue;
+ size_t len = sizeof(lvalue);
+
+ if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1) {
+ ret = -1;
+ } else {
+ if (oldlen) {
+ lvalue = scale_to_guest_pages(lvalue);
+ (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue);
+ }
+ holdlen = sizeof(abi_ulong);
+ ret = 0;
+ }
+ goto out;
+ }
+
+ if (oid_hw_pagesizes && snamep[1] == oid_hw_pagesizes) {
+ if (oldlen) {
+ (*(abi_ulong *)holdp) = tswapal((abi_ulong)TARGET_PAGE_SIZE);
+ ((abi_ulong *)holdp)[1] = 0;
+ }
+ holdlen = sizeof(abi_ulong) * 2;
+ ret = 0;
+ goto out;
+ }
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#ifdef TARGET_ABI32
+ /*
+ * For long and ulong with a 64-bit host and a 32-bit target we have to do
+ * special things. holdlen here is the length provided by the target to the
+ * system call. So we allocate a buffer twice as large because longs are
+ * twice as big on the host which will be writing them. In h2g_old_sysctl
+ * we'll adjust them and adjust the length.
+ */
+ if (kind == CTLTYPE_LONG || kind == CTLTYPE_ULONG) {
+ old_holdp = holdp;
+ holdlen = holdlen * 2;
+ holdp = g_malloc(holdlen);
+ }
+#endif
+
+ ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
+ if (!ret && (holdp != 0)) {
+
+ if (snamep[0] == CTL_SYSCTL) {
+ switch (snamep[1]) {
+ case CTL_SYSCTL_NEXT:
+ case CTL_SYSCTL_NAME2OID:
+ case CTL_SYSCTL_NEXTNOSKIP:
+ /*
+ * All of these return an OID array, so we need to convert to
+ * target.
+ */
+ sysctl_name2oid(holdp, holdlen);
+ break;
+
+ case CTL_SYSCTL_OIDFMT:
+ /* Handle oidfmt */
+ sysctl_oidfmt(holdp);
+ break;
+ case CTL_SYSCTL_OIDDESCR:
+ case CTL_SYSCTL_OIDLABEL:
+ default:
+ /* Handle it based on the type */
+ h2g_old_sysctl(holdp, &holdlen, kind);
+ /* NB: None of these are LONG or ULONG */
+ break;
+ }
+ } else {
+ /*
+ * Need to convert from host to target. All the weird special cases
+ * are handled above.
+ */
+ h2g_old_sysctl(holdp, &holdlen, kind);
+#ifdef TARGET_ABI32
+ /*
+ * For the 32-bit on 64-bit case, for longs we need to copy the
+ * now-converted buffer to the target and free the buffer.
+ */
+ if (kind == CTLTYPE_LONG || kind == CTLTYPE_ULONG) {
+ memcpy(old_holdp, holdp, holdlen);
+ g_free(holdp);
+ holdp = old_holdp;
+ }
+#endif
+ }
+ }
+
+out:
+ *holdlenp = holdlen;
+ return ret;
+}
+
+/*
+ * This syscall was created to make sysctlbyname(3) more efficient, but we can't
+ * really provide it in bsd-user. Notably, we must always translate the names
+ * independently since some sysctl values have to be faked for the target
+ * environment, so it still has to break down to two syscalls for the underlying
+ * implementation.
+ */
+abi_long do_freebsd_sysctlbyname(CPUArchState *env, abi_ulong namep,
+ int32_t namelen, abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp,
+ abi_ulong newlen)
+{
+ abi_long ret = -TARGET_EFAULT;
+ void *holdp = NULL, *hnewp = NULL;
+ char *snamep = NULL;
+ int oid[CTL_MAXNAME + 2];
+ size_t holdlen, oidplen;
+ abi_ulong oldlen = 0;
+
+ /* oldlenp is read/write, pre-check here for write */
+ if (oldlenp) {
+ if (!access_ok(VERIFY_WRITE, oldlenp, sizeof(abi_ulong)) ||
+ get_user_ual(oldlen, oldlenp)) {
+ goto out;
+ }
+ }
+ snamep = lock_user_string(namep);
+ if (snamep == NULL) {
+ goto out;
+ }
+ if (newp) {
+ hnewp = lock_user(VERIFY_READ, newp, newlen, 1);
+ if (hnewp == NULL) {
+ goto out;
+ }
+ }
+ if (oldp) {
+ holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0);
+ if (holdp == NULL) {
+ goto out;
+ }
+ }
+ holdlen = oldlen;
+
+ oidplen = ARRAY_SIZE(oid);
+ if (sysctlnametomib(snamep, oid, &oidplen) != 0) {
+ ret = -TARGET_EINVAL;
+ goto out;
+ }
+
+ ret = do_freebsd_sysctl_oid(env, oid, oidplen, holdp, &holdlen, hnewp,
+ newlen);
+
+ /*
+ * writeability pre-checked above. __sysctl(2) returns ENOMEM and updates
+ * oldlenp for the proper size to use.
+ */
+ if (oldlenp && (ret == 0 || ret == -TARGET_ENOMEM)) {
+ put_user_ual(holdlen, oldlenp);
+ }
+out:
+ unlock_user(snamep, namep, 0);
+ unlock_user(holdp, oldp, ret == 0 ? holdlen : 0);
+ unlock_user(hnewp, newp, 0);
+
+ return ret;
+}
+
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+ abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
+{
+ abi_long ret = -TARGET_EFAULT;
+ void *hnamep, *holdp = NULL, *hnewp = NULL;
+ size_t holdlen;
+ abi_ulong oldlen = 0;
+ int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i;
+
+ /* oldlenp is read/write, pre-check here for write */
+ if (oldlenp) {
+ if (!access_ok(VERIFY_WRITE, oldlenp, sizeof(abi_ulong)) ||
+ get_user_ual(oldlen, oldlenp)) {
+ goto out;
+ }
+ }
+ hnamep = lock_user(VERIFY_READ, namep, namelen, 1);
+ if (hnamep == NULL) {
+ goto out;
+ }
+ if (newp) {
+ hnewp = lock_user(VERIFY_READ, newp, newlen, 1);
+ if (hnewp == NULL) {
+ goto out;
+ }
+ }
+ if (oldp) {
+ holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0);
+ if (holdp == NULL) {
+ goto out;
+ }
+ }
+ holdlen = oldlen;
+ for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++, q++) {
+ *q = tswap32(*p);
+ }
+
+ ret = do_freebsd_sysctl_oid(env, snamep, namelen, holdp, &holdlen, hnewp,
+ newlen);
+
+ /*
+ * writeability pre-checked above. __sysctl(2) returns ENOMEM and updates
+ * oldlenp for the proper size to use.
+ */
+ if (oldlenp && (ret == 0 || ret == -TARGET_ENOMEM)) {
+ put_user_ual(holdlen, oldlenp);
+ }
+ unlock_user(hnamep, namep, 0);
+ unlock_user(holdp, oldp, ret == 0 ? holdlen : 0);
+out:
+ g_free(snamep);
+ return ret;
+}
+
/* sysarch() is architecture dependent. */
abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
{
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 57996ca..179a20c 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -491,6 +491,21 @@
ret = do_bsd_undelete(arg1);
break;
+ /*
+ * sys{ctl, arch, call}
+ */
+ case TARGET_FREEBSD_NR___sysctl: /* sysctl(3) */
+ ret = do_freebsd_sysctl(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+ break;
+
+ case TARGET_FREEBSD_NR___sysctlbyname: /* sysctlbyname(2) */
+ ret = do_freebsd_sysctlbyname(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+ break;
+
+ case TARGET_FREEBSD_NR_sysarch: /* sysarch(2) */
+ ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
+ break;
+
default:
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
ret = -TARGET_ENOSYS;
@@ -512,7 +527,7 @@
abi_long arg8)
{
CPUState *cpu = env_cpu(cpu_env);
- int ret;
+ abi_long ret;
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if (do_strace) {
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 4e7b8b1..41d84e0 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -253,6 +253,11 @@
int host_to_target_errno(int err);
/* os-sys.c */
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+ abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen);
+abi_long do_freebsd_sysctlbyname(CPUArchState *env, abi_ulong namep,
+ int32_t namelen, abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp,
+ abi_ulong newlen);
abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2);
/* user access */
diff --git a/configure b/configure
index f5cfcd5..50a0b80 100755
--- a/configure
+++ b/configure
@@ -1347,7 +1347,7 @@
error_exit "-static-pie not available due to missing toolchain support"
else
pie="no"
- QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS"
+ QEMU_CFLAGS="-fno-pie $QEMU_CFLAGS"
fi
elif test "$pie" = "no"; then
if compile_prog "-Werror -fno-pie" "-no-pie"; then
diff --git a/docs/devel/tcg-ops.rst b/docs/devel/tcg-ops.rst
index 9adc0c9..561c416 100644
--- a/docs/devel/tcg-ops.rst
+++ b/docs/devel/tcg-ops.rst
@@ -7,67 +7,51 @@
Introduction
============
-TCG (Tiny Code Generator) began as a generic backend for a C
-compiler. It was simplified to be used in QEMU. It also has its roots
-in the QOP code generator written by Paul Brook.
+TCG (Tiny Code Generator) began as a generic backend for a C compiler.
+It was simplified to be used in QEMU. It also has its roots in the
+QOP code generator written by Paul Brook.
Definitions
===========
-TCG receives RISC-like *TCG ops* and performs some optimizations on them,
-including liveness analysis and trivial constant expression
-evaluation. TCG ops are then implemented in the host CPU back end,
-also known as the TCG target.
-
-The TCG *target* is the architecture for which we generate the
-code. It is of course not the same as the "target" of QEMU which is
-the emulated architecture. As TCG started as a generic C backend used
-for cross compiling, it is assumed that the TCG target is different
-from the host, although it is never the case for QEMU.
+The TCG *target* is the architecture for which we generate the code.
+It is of course not the same as the "target" of QEMU which is the
+emulated architecture. As TCG started as a generic C backend used
+for cross compiling, the assumption was that TCG target might be
+different from the host, although this is never the case for QEMU.
In this document, we use *guest* to specify what architecture we are
emulating; *target* always means the TCG target, the machine on which
we are running QEMU.
-A TCG *function* corresponds to a QEMU Translated Block (TB).
-
-A TCG *temporary* is a variable only live in a basic block. Temporaries are allocated explicitly in each function.
-
-A TCG *local temporary* is a variable only live in a function. Local temporaries are allocated explicitly in each function.
-
-A TCG *global* is a variable which is live in all the functions
-(equivalent of a C global variable). They are defined before the
-functions defined. A TCG global can be a memory location (e.g. a QEMU
-CPU register), a fixed host register (e.g. the QEMU CPU state pointer)
-or a memory location which is stored in a register outside QEMU TBs
-(not implemented yet).
-
-A TCG *basic block* corresponds to a list of instructions terminated
-by a branch instruction.
-
An operation with *undefined behavior* may result in a crash.
An operation with *unspecified behavior* shall not crash. However,
the result may be one of several possibilities so may be considered
an *undefined result*.
-Intermediate representation
-===========================
+Basic Blocks
+============
-Introduction
-------------
+A TCG *basic block* is a single entry, multiple exit region which
+corresponds to a list of instructions terminated by a label, or
+any branch instruction.
-TCG instructions operate on variables which are temporaries, local
-temporaries or globals. TCG instructions and variables are strongly
-typed. Two types are supported: 32 bit integers and 64 bit
-integers. Pointers are defined as an alias to 32 bit or 64 bit
-integers depending on the TCG target word size.
+A TCG *extended basic block* is a single entry, multiple exit region
+which corresponds to a list of instructions terminated by a label or
+an unconditional branch. Specifically, an extended basic block is
+a sequence of basic blocks connected by the fall-through paths of
+zero or more conditional branch instructions.
-Each instruction has a fixed number of output variable operands, input
-variable operands and always constant operands.
+Operations
+==========
-The notable exception is the call instruction which has a variable
-number of outputs and inputs.
+TCG instructions or *ops* operate on TCG *variables*, both of which
+are strongly typed. Each instruction has a fixed number of output
+variable operands, input variable operands and constant operands.
+Vector instructions have a field specifying the element size within
+the vector. The notable exception is the call instruction which has
+a variable number of outputs and inputs.
In the textual form, output operands usually come first, followed by
input operands, followed by constant operands. The output type is
@@ -77,68 +61,127 @@
add_i32 t0, t1, t2 /* (t0 <- t1 + t2) */
+Variables
+=========
-Assumptions
------------
+* ``TEMP_FIXED``
-Basic blocks
-^^^^^^^^^^^^
+ There is one TCG *fixed global* variable, ``cpu_env``, which is
+ live in all translation blocks, and holds a pointer to ``CPUArchState``.
+ This variable is held in a host cpu register at all times in all
+ translation blocks.
-* Basic blocks end after branches (e.g. brcond_i32 instruction),
- goto_tb and exit_tb instructions.
+* ``TEMP_GLOBAL``
-* Basic blocks start after the end of a previous basic block, or at a
- set_label instruction.
+ A TCG *global* is a variable which is live in all translation blocks,
+ and corresponds to memory location that is within ``CPUArchState``.
+ These may be specified as an offset from ``cpu_env``, in which case
+ they are called *direct globals*, or may be specified as an offset
+ from a direct global, in which case they are called *indirect globals*.
+ Even indirect globals should still reference memory within
+ ``CPUArchState``. All TCG globals are defined during
+ ``TCGCPUOps.initialize``, before any translation blocks are generated.
-After the end of a basic block, the content of temporaries is
-destroyed, but local temporaries and globals are preserved.
+* ``TEMP_CONST``
-Floating point types
-^^^^^^^^^^^^^^^^^^^^
+ A TCG *constant* is a variable which is live throughout the entire
+ translation block, and contains a constant value. These variables
+ are allocated on demand during translation and are hashed so that
+ there is exactly one variable holding a given value.
-* Floating point types are not supported yet
+* ``TEMP_TB``
-Pointers
-^^^^^^^^
+ A TCG *translation block temporary* is a variable which is live
+ throughout the entire translation block, but dies on any exit.
+ These temporaries are allocated explicitly during translation.
-* Depending on the TCG target, pointer size is 32 bit or 64
- bit. The type ``TCG_TYPE_PTR`` is an alias to ``TCG_TYPE_I32`` or
- ``TCG_TYPE_I64``.
+* ``TEMP_EBB``
+
+ A TCG *extended basic block temporary* is a variable which is live
+ throughout an extended basic block, but dies on any exit.
+ These temporaries are allocated explicitly during translation.
+
+Types
+=====
+
+* ``TCG_TYPE_I32``
+
+ A 32-bit integer.
+
+* ``TCG_TYPE_I64``
+
+ A 64-bit integer. For 32-bit hosts, such variables are split into a pair
+ of variables with ``type=TCG_TYPE_I32`` and ``base_type=TCG_TYPE_I64``.
+ The ``temp_subindex`` for each indicates where it falls within the
+ host-endian representation.
+
+* ``TCG_TYPE_PTR``
+
+ An alias for ``TCG_TYPE_I32`` or ``TCG_TYPE_I64``, depending on the size
+ of a pointer for the host.
+
+* ``TCG_TYPE_REG``
+
+ An alias for ``TCG_TYPE_I32`` or ``TCG_TYPE_I64``, depending on the size
+ of the integer registers for the host. This may be larger
+ than ``TCG_TYPE_PTR`` depending on the host ABI.
+
+* ``TCG_TYPE_I128``
+
+ A 128-bit integer. For all hosts, such variables are split into a number
+ of variables with ``type=TCG_TYPE_REG`` and ``base_type=TCG_TYPE_I128``.
+ The ``temp_subindex`` for each indicates where it falls within the
+ host-endian representation.
+
+* ``TCG_TYPE_V64``
+
+ A 64-bit vector. This type is valid only if the TCG target
+ sets ``TCG_TARGET_HAS_v64``.
+
+* ``TCG_TYPE_V128``
+
+ A 128-bit vector. This type is valid only if the TCG target
+ sets ``TCG_TARGET_HAS_v128``.
+
+* ``TCG_TYPE_V256``
+
+ A 256-bit vector. This type is valid only if the TCG target
+ sets ``TCG_TARGET_HAS_v256``.
Helpers
-^^^^^^^
+=======
-* Using the tcg_gen_helper_x_y it is possible to call any function
- taking i32, i64 or pointer types. By default, before calling a helper,
- all globals are stored at their canonical location and it is assumed
- that the function can modify them. By default, the helper is allowed to
- modify the CPU state or raise an exception.
+Helpers are registered in a guest-specific ``helper.h``,
+which is processed to generate ``tcg_gen_helper_*`` functions.
+With these functions it is possible to call a function taking
+i32, i64, i128 or pointer types.
- This can be overridden using the following function modifiers:
+By default, before calling a helper, all globals are stored at their
+canonical location. By default, the helper is allowed to modify the
+CPU state (including the state represented by tcg globals)
+or may raise an exception. This default can be overridden using the
+following function modifiers:
- - ``TCG_CALL_NO_READ_GLOBALS`` means that the helper does not read globals,
- either directly or via an exception. They will not be saved to their
- canonical locations before calling the helper.
+* ``TCG_CALL_NO_WRITE_GLOBALS``
- - ``TCG_CALL_NO_WRITE_GLOBALS`` means that the helper does not modify any globals.
- They will only be saved to their canonical location before calling helpers,
- but they won't be reloaded afterwards.
+ The helper does not modify any globals, but may read them.
+ Globals will be saved to their canonical location before calling helpers,
+ but need not be reloaded afterwards.
- - ``TCG_CALL_NO_SIDE_EFFECTS`` means that the call to the function is removed if
- the return value is not used.
+* ``TCG_CALL_NO_READ_GLOBALS``
- Note that ``TCG_CALL_NO_READ_GLOBALS`` implies ``TCG_CALL_NO_WRITE_GLOBALS``.
+ The helper does not read globals, either directly or via an exception.
+ They will not be saved to their canonical locations before calling
+ the helper. This implies ``TCG_CALL_NO_WRITE_GLOBALS``.
- On some TCG targets (e.g. x86), several calling conventions are
- supported.
+* ``TCG_CALL_NO_SIDE_EFFECTS``
-Branches
-^^^^^^^^
-
-* Use the instruction 'br' to jump to a label.
+ The call to the helper function may be removed if the return value is
+ not used. This means that it may not modify any CPU state nor may it
+ raise an exception.
Code Optimizations
-------------------
+==================
When generating instructions, you can count on at least the following
optimizations:
@@ -908,20 +951,9 @@
often modified, e.g. the integer registers and the condition
codes. TCG will be able to use host registers to store them.
-- Avoid globals stored in fixed registers. They must be used only to
- store the pointer to the CPU state and possibly to store a pointer
- to a register window.
-
-- Use temporaries. Use local temporaries only when really needed,
- e.g. when you need to use a value after a jump. Local temporaries
- introduce a performance hit in the current TCG implementation: their
- content is saved to memory at end of each basic block.
-
-- Free temporaries and local temporaries when they are no longer used
- (tcg_temp_free). Since tcg_const_x() also creates a temporary, you
- should free it after it is used. Freeing temporaries does not yield
- a better generated code, but it reduces the memory usage of TCG and
- the speed of the translation.
+- Free temporaries when they are no longer used (``tcg_temp_free``).
+ Since ``tcg_const_x`` also creates a temporary, you should free it
+ after it is used.
- Don't hesitate to use helpers for complicated or seldom used guest
instructions. There is little performance advantage in using TCG to
@@ -932,10 +964,6 @@
the instruction is mostly doing loads and stores, and in those cases
inline TCG may still be faster for longer sequences.
-- The hard limit on the number of TCG instructions you can generate
- per guest instruction is set by ``MAX_OP_PER_INSTR`` in ``exec-all.h`` --
- you cannot exceed this without risking a buffer overrun.
-
- Use the 'discard' instruction if you know that TCG won't be able to
prove that a given global is "dead" at a given program point. The
x86 guest uses it to improve the condition codes optimisation.
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index d5a4f30..be920d4 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -54,9 +54,6 @@
# error TARGET_PAGE_BITS must be defined in cpu-param.h
# endif
#endif
-#ifndef TARGET_TB_PCREL
-# define TARGET_TB_PCREL 0
-#endif
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 0e36f4d..e092543 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -447,6 +447,7 @@
* probe_access_flags:
* @env: CPUArchState
* @addr: guest virtual address to look up
+ * @size: size of the access
* @access_type: read, write or execute permission
* @mmu_idx: MMU index to use for lookup
* @nonfault: suppress the fault
@@ -461,7 +462,7 @@
* Do handle clean pages, so exclude TLB_NOTDIRY from the returned flags.
* For simplicity, all "mmio-like" flags are folded to TLB_MMIO.
*/
-int probe_access_flags(CPUArchState *env, target_ulong addr,
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t retaddr);
@@ -474,7 +475,7 @@
* and must be consumed or copied immediately, before any further
* access or changes to TLB @mmu_idx.
*/
-int probe_access_full(CPUArchState *env, target_ulong addr,
+int probe_access_full(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost,
CPUTLBEntryFull **pfull, uintptr_t retaddr);
@@ -505,22 +506,20 @@
};
struct TranslationBlock {
-#if !TARGET_TB_PCREL
/*
* Guest PC corresponding to this block. This must be the true
* virtual address. Therefore e.g. x86 stores EIP + CS_BASE, and
* targets like Arm, MIPS, HP-PA, which reuse low bits for ISA or
* privilege, must store those bits elsewhere.
*
- * If TARGET_TB_PCREL, the opcodes for the TranslationBlock are
- * written such that the TB is associated only with the physical
- * page and may be run in any virtual address context. In this case,
- * PC must always be taken from ENV in a target-specific manner.
+ * If CF_PCREL, the opcodes for the TranslationBlock are written
+ * such that the TB is associated only with the physical page and
+ * may be run in any virtual address context. In this case, PC
+ * must always be taken from ENV in a target-specific manner.
* Unwind information is taken as offsets from the page, to be
* deposited into the "current" PC.
*/
target_ulong pc;
-#endif
/*
* Target-specific data associated with the TranslationBlock, e.g.:
@@ -545,6 +544,7 @@
#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
+#define CF_PCREL 0x00200000 /* Opcodes in TB are PC-relative */
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
#define CF_CLUSTER_SHIFT 24
@@ -613,16 +613,6 @@
uintptr_t jmp_dest[2];
};
-/* Hide the read to avoid ifdefs for TARGET_TB_PCREL. */
-static inline target_ulong tb_pc(const TranslationBlock *tb)
-{
-#if TARGET_TB_PCREL
- qemu_build_not_reached();
-#else
- return tb->pc;
-#endif
-}
-
/* Hide the qatomic_read to make code a little easier on the eyes */
static inline uint32_t tb_cflags(const TranslationBlock *tb)
{
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 166170b..aff35d6 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -9,22 +9,14 @@
static inline void gen_io_start(void)
{
- TCGv_i32 tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env,
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
offsetof(ArchCPU, parent_obj.can_do_io) -
offsetof(ArchCPU, env));
- tcg_temp_free_i32(tmp);
}
static inline void gen_tb_start(const TranslationBlock *tb)
{
- TCGv_i32 count;
-
- if (tb_cflags(tb) & CF_USE_ICOUNT) {
- count = tcg_temp_local_new_i32();
- } else {
- count = tcg_temp_new_i32();
- }
+ TCGv_i32 count = tcg_temp_new_i32();
tcg_gen_ld_i32(count, cpu_env,
offsetof(ArchCPU, neg.icount_decr.u32) -
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index b8d1140..f863a6e 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -18,6 +18,8 @@
#ifndef EXEC_HELPER_HEAD_H
#define EXEC_HELPER_HEAD_H
+#include "fpu/softfloat-types.h"
+
#define HELPER(name) glue(helper_, name)
/* Some types that make sense in C, but not for TCG. */
diff --git a/include/exec/translator.h b/include/exec/translator.h
index af2ff95..8b36690 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -37,7 +37,7 @@
* This function must be provided by the target, which should create
* the target-specific DisasContext, and then invoke translator_loop.
*/
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc);
/**
@@ -146,7 +146,7 @@
* - When single-stepping is enabled (system-wide or on the current vCPU).
* - When too many instructions have been translated.
*/
-void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc,
const TranslatorOps *ops, DisasContextBase *db);
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index 839d91c..353d430 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -828,14 +828,12 @@
#if TARGET_LONG_BITS == 32
#define tcg_temp_new() tcg_temp_new_i32()
#define tcg_global_mem_new tcg_global_mem_new_i32
-#define tcg_temp_local_new() tcg_temp_local_new_i32()
#define tcg_temp_free tcg_temp_free_i32
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
#else
#define tcg_temp_new() tcg_temp_new_i64()
#define tcg_global_mem_new tcg_global_mem_new_i64
-#define tcg_temp_local_new() tcg_temp_local_new_i64()
#define tcg_temp_free tcg_temp_free_i64
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
@@ -1285,6 +1283,11 @@
glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
}
+static inline void tcg_gen_movi_ptr(TCGv_ptr d, intptr_t s)
+{
+ glue(tcg_gen_movi_,PTR)((NAT)d, s);
+}
+
static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
intptr_t b, TCGLabel *label)
{
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 59854f9..7e2b954 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -431,13 +431,15 @@
} TCGTempVal;
typedef enum TCGTempKind {
- /* Temp is dead at the end of all basic blocks. */
- TEMP_NORMAL,
- /* Temp is live across conditional branch, but dead otherwise. */
+ /*
+ * Temp is dead at the end of the extended basic block (EBB),
+ * the single-entry multiple-exit region that falls through
+ * conditional branches.
+ */
TEMP_EBB,
- /* Temp is saved across basic blocks but dead at the end of TBs. */
- TEMP_LOCAL,
- /* Temp is saved across both basic blocks and translation blocks. */
+ /* Temp is live across the entire translation block, but dead at end. */
+ TEMP_TB,
+ /* Temp is live across the entire translation block, and between them. */
TEMP_GLOBAL,
/* Temp is in a fixed register. */
TEMP_FIXED,
@@ -610,7 +612,7 @@
#endif
GHashTable *const_table[TCG_TYPE_COUNT];
- TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
+ TCGTempSet free_temps[TCG_TYPE_COUNT];
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
QTAILQ_HEAD(, TCGOp) ops, free_ops;
@@ -853,7 +855,7 @@
TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
intptr_t, const char *);
-TCGTemp *tcg_temp_new_internal(TCGType, bool);
+TCGTemp *tcg_temp_new_internal(TCGType, TCGTempKind);
void tcg_temp_free_internal(TCGTemp *);
TCGv_vec tcg_temp_new_vec(TCGType type);
TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match);
@@ -890,15 +892,16 @@
return temp_tcgv_i32(t);
}
-static inline TCGv_i32 tcg_temp_new_i32(void)
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
+static inline TCGv_i32 tcg_temp_ebb_new_i32(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, false);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB);
return temp_tcgv_i32(t);
}
-static inline TCGv_i32 tcg_temp_local_new_i32(void)
+static inline TCGv_i32 tcg_temp_new_i32(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, true);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB);
return temp_tcgv_i32(t);
}
@@ -909,27 +912,29 @@
return temp_tcgv_i64(t);
}
-static inline TCGv_i64 tcg_temp_new_i64(void)
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
+static inline TCGv_i64 tcg_temp_ebb_new_i64(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, false);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB);
return temp_tcgv_i64(t);
}
-static inline TCGv_i64 tcg_temp_local_new_i64(void)
+static inline TCGv_i64 tcg_temp_new_i64(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, true);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB);
return temp_tcgv_i64(t);
}
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
+static inline TCGv_i128 tcg_temp_ebb_new_i128(void)
+{
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB);
+ return temp_tcgv_i128(t);
+}
+
static inline TCGv_i128 tcg_temp_new_i128(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, false);
- return temp_tcgv_i128(t);
-}
-
-static inline TCGv_i128 tcg_temp_local_new_i128(void)
-{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, true);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB);
return temp_tcgv_i128(t);
}
@@ -940,15 +945,16 @@
return temp_tcgv_ptr(t);
}
-static inline TCGv_ptr tcg_temp_new_ptr(void)
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
+static inline TCGv_ptr tcg_temp_ebb_new_ptr(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, false);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB);
return temp_tcgv_ptr(t);
}
-static inline TCGv_ptr tcg_temp_local_new_ptr(void)
+static inline TCGv_ptr tcg_temp_new_ptr(void)
{
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, true);
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB);
return temp_tcgv_ptr(t);
}
@@ -1054,8 +1060,6 @@
/* Allocate a new temporary and initialize it with a constant. */
TCGv_i32 tcg_const_i32(int32_t val);
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);
TCGv_vec tcg_const_zeros_vec(TCGType);
TCGv_vec tcg_const_ones_vec(TCGType);
TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec);
@@ -1083,11 +1087,9 @@
#if UINTPTR_MAX == UINT32_MAX
# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i32((intptr_t)(x)))
-# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i32((intptr_t)(x)))
# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i32((intptr_t)(x)))
#else
# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i64((intptr_t)(x)))
-# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i64((intptr_t)(x)))
# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i64((intptr_t)(x)))
#endif
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 2aa85d3..fee4103 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1189,9 +1189,7 @@
}
memcpy(cmd, pstart, len);
cmd[len] = '\0';
- if (name[0] == '\0') {
- readline_add_completion_of(mon->rs, name, cmd);
- }
+ readline_add_completion_of(mon->rs, name, cmd);
if (*p == '\0') {
break;
}
@@ -1335,9 +1333,7 @@
/* block device name completion */
readline_set_completion_index(mon->rs, strlen(str));
while ((blk = blk_next(blk)) != NULL) {
- if (str[0] == '\0') {
- readline_add_completion_of(mon->rs, str, blk_name(blk));
- }
+ readline_add_completion_of(mon->rs, str, blk_name(blk));
}
break;
case 's':
diff --git a/semihosting/uaccess.c b/semihosting/uaccess.c
index 8018828..7505eb6 100644
--- a/semihosting/uaccess.c
+++ b/semihosting/uaccess.c
@@ -37,7 +37,7 @@
/* Find the number of bytes remaining in the page. */
left_in_page = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
- flags = probe_access_flags(env, addr, MMU_DATA_LOAD,
+ flags = probe_access_flags(env, addr, 0, MMU_DATA_LOAD,
mmu_idx, true, &h, 0);
if (flags & TLB_INVALID_MASK) {
return -1;
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index df54b91..47143ed 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2637,7 +2637,7 @@
} else {
/* RAM case */
ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
- memcpy(ram_ptr, buf, l);
+ memmove(ram_ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index f9bcdeb..716b083 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -3043,7 +3043,7 @@
.disas_log = alpha_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/arm/monitor.c b/target/arm/arm-qmp-cmds.c
similarity index 89%
rename from target/arm/monitor.c
rename to target/arm/arm-qmp-cmds.c
index ecdd5ee..c8fa524 100644
--- a/target/arm/monitor.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -227,3 +227,31 @@
return expansion_info;
}
+
+static void arm_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **cpu_list = user_data;
+ CpuDefinitionInfo *info;
+ const char *typename;
+
+ typename = object_class_get_name(oc);
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strndup(typename,
+ strlen(typename) - strlen("-" TYPE_ARM_CPU));
+ info->q_typename = g_strdup(typename);
+
+ QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
+
+ list = object_class_get_list(TYPE_ARM_CPU, false);
+ g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
+ g_slist_free(list);
+
+ return cpu_list;
+}
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 53cac9c8..b7bde18 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -31,8 +31,6 @@
# define TARGET_PAGE_BITS_VARY
# define TARGET_PAGE_BITS_MIN 10
-# define TARGET_TB_PCREL 1
-
/*
* Cache the attrs and shareability fields from the page table entry.
*
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 0b333a7..5182ed0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -78,17 +78,17 @@
void arm_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- /* The program counter is always up to date with TARGET_TB_PCREL. */
- if (!TARGET_TB_PCREL) {
+ /* The program counter is always up to date with CF_PCREL. */
+ if (!(tb_cflags(tb) & CF_PCREL)) {
CPUARMState *env = cs->env_ptr;
/*
* It's OK to look at env for the current mode here, because it's
* never possible for an AArch64 TB to chain to an AArch32 TB.
*/
if (is_a64(env)) {
- env->pc = tb_pc(tb);
+ env->pc = tb->pc;
} else {
- env->regs[15] = tb_pc(tb);
+ env->regs[15] = tb->pc;
}
}
}
@@ -100,7 +100,7 @@
CPUARMState *env = cs->env_ptr;
if (is_a64(env)) {
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(tb) & CF_PCREL) {
env->pc = (env->pc & TARGET_PAGE_MASK) | data[0];
} else {
env->pc = data[0];
@@ -108,7 +108,7 @@
env->condexec_bits = 0;
env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
} else {
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(tb) & CF_PCREL) {
env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0];
} else {
env->regs[15] = data[0];
@@ -1557,6 +1557,11 @@
Error *local_err = NULL;
bool no_aa32 = false;
+ /* Use pc-relative instructions in system-mode */
+#ifndef CONFIG_USER_ONLY
+ cs->tcg_cflags |= CF_PCREL;
+#endif
+
/* If we needed to query the host kernel for the CPU features
* then it's possible that might have failed in the initfn, but
* this is the first point where we can report it.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 14af7ba..82c546f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -23,7 +23,6 @@
#include "sysemu/cpu-timers.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
-#include "qapi/qapi-commands-machine-target.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
#ifdef CONFIG_TCG
@@ -9188,34 +9187,6 @@
g_slist_free(list);
}
-static void arm_cpu_add_definition(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfo *info;
- const char *typename;
-
- typename = object_class_get_name(oc);
- info = g_malloc0(sizeof(*info));
- info->name = g_strndup(typename,
- strlen(typename) - strlen("-" TYPE_ARM_CPU));
- info->q_typename = g_strdup(typename);
-
- QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
-
- list = object_class_get_list(TYPE_ARM_CPU, false);
- g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
- g_slist_free(list);
-
- return cpu_list;
-}
-
/*
* Private utility function for define_one_arm_cp_reg_with_opaque():
* add a single reginfo struct to the hash table.
diff --git a/target/arm/meson.build b/target/arm/meson.build
index a5191b5..6226098 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -20,8 +20,8 @@
arm_softmmu_ss.add(files(
'arch_dump.c',
'arm-powerctl.c',
+ 'arm-qmp-cmds.c',
'machine.c',
- 'monitor.c',
'ptw.c',
))
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index be0cc6b..8541ef5 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -259,7 +259,7 @@
int flags;
env->tlb_fi = fi;
- flags = probe_access_full(env, addr, MMU_DATA_LOAD,
+ flags = probe_access_full(env, addr, 0, MMU_DATA_LOAD,
arm_to_core_mmu_idx(s2_mmu_idx),
true, &ptw->out_host, &full, 0);
env->tlb_fi = NULL;
@@ -411,7 +411,7 @@
void *discard;
env->tlb_fi = fi;
- flags = probe_access_flags(env, ptw->out_virt, MMU_DATA_STORE,
+ flags = probe_access_flags(env, ptw->out_virt, 0, MMU_DATA_STORE,
arm_to_core_mmu_idx(ptw->in_ptw_idx),
true, &discard, 0);
env->tlb_fi = NULL;
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index 98bcf59..fee3c7e 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -118,7 +118,7 @@
* valid. Indicate to probe_access_flags no-fault, then assert that
* we received a valid page.
*/
- flags = probe_access_full(env, ptr, ptr_access, ptr_mmu_idx,
+ flags = probe_access_full(env, ptr, 0, ptr_access, ptr_mmu_idx,
ra == 0, &host, &full, ra);
assert(!(flags & TLB_INVALID_MASK));
@@ -154,7 +154,7 @@
*/
in_page = -(ptr | TARGET_PAGE_MASK);
if (unlikely(ptr_size > in_page)) {
- flags |= probe_access_full(env, ptr + in_page, ptr_access,
+ flags |= probe_access_full(env, ptr + in_page, 0, ptr_access,
ptr_mmu_idx, ra == 0, &host, &full, ra);
assert(!(flags & TLB_INVALID_MASK));
}
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index 521fc9b..9a8951a 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -5352,11 +5352,11 @@
addr = useronly_clean_ptr(addr);
#ifdef CONFIG_USER_ONLY
- flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault,
+ flags = probe_access_flags(env, addr, 0, access_type, mmu_idx, nofault,
&info->host, retaddr);
#else
CPUTLBEntryFull *full;
- flags = probe_access_full(env, addr, access_type, mmu_idx, nofault,
+ flags = probe_access_full(env, addr, 0, access_type, mmu_idx, nofault,
&info->host, &full, retaddr);
#endif
info->flags = flags;
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index da9f877..f092aec 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -143,7 +143,7 @@
static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
tcg_gen_addi_i64(dest, cpu_pc, (s->pc_curr - s->pc_save) + diff);
} else {
tcg_gen_movi_i64(dest, s->pc_curr + diff);
@@ -393,7 +393,7 @@
* update to pc to the unlinked path. A long chain of links
* can thus avoid many updates to the PC.
*/
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
gen_a64_update_pc(s, diff);
tcg_gen_goto_tb(n);
} else {
@@ -436,12 +436,6 @@
return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
}
-TCGv_i64 new_tmp_a64_local(DisasContext *s)
-{
- assert(s->tmp_a64_count < TMP_A64_MAX);
- return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_local_new_i64();
-}
-
TCGv_i64 new_tmp_a64_zero(DisasContext *s)
{
TCGv_i64 t = new_tmp_a64(s);
@@ -4297,7 +4291,7 @@
if (page) {
/* ADRP (page based) */
offset <<= 12;
- /* The page offset is ok for TARGET_TB_PCREL. */
+ /* The page offset is ok for CF_PCREL. */
offset -= s->pc_curr & 0xfff;
}
@@ -14651,7 +14645,7 @@
* that the TLB entry must be present and valid, and thus this
* access will never raise an exception.
*/
- flags = probe_access_full(env, addr, MMU_INST_FETCH, mmu_idx,
+ flags = probe_access_full(env, addr, 0, MMU_INST_FETCH, mmu_idx,
false, &host, &full, 0);
assert(!(flags & TLB_INVALID_MASK));
@@ -14809,7 +14803,7 @@
DisasContext *dc = container_of(dcbase, DisasContext, base);
target_ulong pc_arg = dc->base.pc_next;
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
pc_arg &= ~TARGET_PAGE_MASK;
}
tcg_gen_insn_start(pc_arg, 0, 0);
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index ad3762d..ca24c39 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -19,7 +19,6 @@
#define TARGET_ARM_TRANSLATE_A64_H
TCGv_i64 new_tmp_a64(DisasContext *s);
-TCGv_i64 new_tmp_a64_local(DisasContext *s);
TCGv_i64 new_tmp_a64_zero(DisasContext *s);
TCGv_i64 cpu_reg(DisasContext *s, int reg);
TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 621a2ab..718a5bc 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -2694,7 +2694,7 @@
return true;
}
- last = tcg_temp_local_new_i32();
+ last = tcg_temp_new_i32();
over = gen_new_label();
find_last_active(s, last, esz, a->pg);
@@ -4342,18 +4342,7 @@
tcg_temp_free_i64(t0);
} else {
TCGLabel *loop = gen_new_label();
- TCGv_ptr tp, i = tcg_const_local_ptr(0);
-
- /* Copy the clean address into a local temp, live across the loop. */
- t0 = clean_addr;
- clean_addr = new_tmp_a64_local(s);
- tcg_gen_mov_i64(clean_addr, t0);
-
- if (base != cpu_env) {
- TCGv_ptr b = tcg_temp_local_new_ptr();
- tcg_gen_mov_ptr(b, base);
- base = b;
- }
+ TCGv_ptr tp, i = tcg_const_ptr(0);
gen_set_label(loop);
@@ -4370,11 +4359,6 @@
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
tcg_temp_free_ptr(i);
-
- if (base != cpu_env) {
- tcg_temp_free_ptr(base);
- assert(len_remain == 0);
- }
}
/*
@@ -4443,18 +4427,7 @@
tcg_temp_free_i64(t0);
} else {
TCGLabel *loop = gen_new_label();
- TCGv_ptr tp, i = tcg_const_local_ptr(0);
-
- /* Copy the clean address into a local temp, live across the loop. */
- t0 = clean_addr;
- clean_addr = new_tmp_a64_local(s);
- tcg_gen_mov_i64(clean_addr, t0);
-
- if (base != cpu_env) {
- TCGv_ptr b = tcg_temp_local_new_ptr();
- tcg_gen_mov_ptr(b, base);
- base = b;
- }
+ TCGv_ptr tp, i = tcg_const_ptr(0);
gen_set_label(loop);
@@ -4471,11 +4444,6 @@
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
tcg_temp_free_ptr(i);
-
- if (base != cpu_env) {
- tcg_temp_free_ptr(base);
- assert(len_remain == 0);
- }
}
/* Predicate register stores can be any multiple of 2. */
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index c23a346..f042069 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -269,7 +269,7 @@
static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
tcg_gen_addi_i32(var, cpu_R[15], (s->pc_curr - s->pc_save) + diff);
} else {
tcg_gen_movi_i32(var, s->pc_curr + diff);
@@ -2620,7 +2620,7 @@
* update to pc to the unlinked path. A long chain of links
* can thus avoid many updates to the PC.
*/
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
gen_update_pc(s, diff);
tcg_gen_goto_tb(n);
} else {
@@ -7136,7 +7136,7 @@
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
}
- addr = tcg_temp_local_new_i32();
+ addr = tcg_temp_new_i32();
load_reg_var(s, addr, a->rn);
tcg_gen_addi_i32(addr, addr, a->imm);
@@ -7289,7 +7289,7 @@
return true;
}
- addr = tcg_temp_local_new_i32();
+ addr = tcg_temp_new_i32();
load_reg_var(s, addr, a->rn);
tcg_gen_addi_i32(addr, addr, a->imm);
@@ -8696,7 +8696,7 @@
* Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
* so that decr stays live after the brcondi.
*/
- TCGv_i32 decr = tcg_temp_local_new_i32();
+ TCGv_i32 decr = tcg_temp_new_i32();
TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
@@ -9542,7 +9542,7 @@
uint32_t condexec_bits;
target_ulong pc_arg = dc->base.pc_next;
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
pc_arg &= ~TARGET_PAGE_MASK;
}
if (dc->eci) {
@@ -9970,7 +9970,7 @@
};
/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc = { };
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 3717824..4001372 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -23,7 +23,7 @@
/* The address of the current instruction being translated. */
target_ulong pc_curr;
/*
- * For TARGET_TB_PCREL, the full value of cpu_pc is not known
+ * For CF_PCREL, the full value of cpu_pc is not known
* (although the page offset is known). For convenience, the
* translation loop uses the full virtual address that triggered
* the translation, from base.pc_start through pc_curr.
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index d013980..a24c23c 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -54,7 +54,8 @@
AVRCPU *cpu = AVR_CPU(cs);
CPUAVRState *env = &cpu->env;
- env->pc_w = tb_pc(tb) / 2; /* internally PC points to words */
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ env->pc_w = tb->pc / 2; /* internally PC points to words */
}
static void avr_restore_state_to_opc(CPUState *cs,
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 2bed56f..e40d8e9 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -3049,7 +3049,7 @@
.disas_log = avr_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc = { };
diff --git a/target/cris/translate.c b/target/cris/translate.c
index fbc3fd5..a959b27 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -1621,7 +1621,7 @@
LOG_DIS("bound.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2);
cris_cc_mask(dc, CC_MASK_NZ);
- l0 = tcg_temp_local_new();
+ l0 = tcg_temp_new();
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
tcg_temp_free(l0);
@@ -2404,8 +2404,8 @@
dc->op1, dc->postinc ? "+]" : "]",
dc->op2);
- l[0] = tcg_temp_local_new();
- l[1] = tcg_temp_local_new();
+ l[0] = tcg_temp_new();
+ l[1] = tcg_temp_new();
insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
cris_cc_mask(dc, CC_MASK_NZ);
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
@@ -3286,7 +3286,7 @@
.disas_log = cris_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index f500e93..9660f28 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -68,9 +68,9 @@
unsigned int size, int mem_index)
{
TCGLabel *l1 = gen_new_label();
- TCGv taddr = tcg_temp_local_new();
- TCGv tval = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
+ TCGv taddr = tcg_temp_new();
+ TCGv tval = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
dc->postinc = 0;
cris_evaluate_flags(dc);
@@ -434,7 +434,7 @@
{
TCGv t;
- t = tcg_temp_local_new();
+ t = tcg_temp_new();
t_gen_zext(t, cpu_R[dc->src], size);
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
tcg_temp_free(t);
@@ -935,7 +935,7 @@
int rd = dc->dst;
TCGv t;
- t = tcg_temp_local_new();
+ t = tcg_temp_new();
insn_len += dec10_prep_move_m(env, dc, 0, size, t);
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
if (dc->dst == 15) {
diff --git a/target/hexagon/README b/target/hexagon/README
index 6cb5aff..2e32639 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -81,7 +81,7 @@
Insn *insn,
Packet *pkt)
{
- TCGv RdV = tcg_temp_local_new();
+ TCGv RdV = tcg_temp_new();
const int RdN = insn->regno[0];
TCGv RsV = hex_gpr[insn->regno[1]];
TCGv RtV = hex_gpr[insn->regno[2]];
@@ -146,16 +146,16 @@
const int VdN = insn->regno[0];
const intptr_t VdV_off =
ctx_future_vreg_off(ctx, VdN, 1, true);
- TCGv_ptr VdV = tcg_temp_local_new_ptr();
+ TCGv_ptr VdV = tcg_temp_new_ptr();
tcg_gen_addi_ptr(VdV, cpu_env, VdV_off);
const int VuN = insn->regno[1];
const intptr_t VuV_off =
vreg_src_off(ctx, VuN);
- TCGv_ptr VuV = tcg_temp_local_new_ptr();
+ TCGv_ptr VuV = tcg_temp_new_ptr();
const int VvN = insn->regno[2];
const intptr_t VvV_off =
vreg_src_off(ctx, VvN);
- TCGv_ptr VvV = tcg_temp_local_new_ptr();
+ TCGv_ptr VvV = tcg_temp_new_ptr();
tcg_gen_addi_ptr(VuV, cpu_env, VuV_off);
tcg_gen_addi_ptr(VvV, cpu_env, VvV_off);
TCGv slot = tcg_constant_tl(insn->slot);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 807037c..ab40cfc 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -23,6 +23,7 @@
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "fpu/softfloat-helpers.h"
+#include "tcg/tcg.h"
static void hexagon_v67_cpu_init(Object *obj)
{
@@ -263,7 +264,8 @@
{
HexagonCPU *cpu = HEXAGON_CPU(cs);
CPUHexagonState *env = &cpu->env;
- env->gpr[HEX_REG_PC] = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ env->gpr[HEX_REG_PC] = tb->pc;
}
static bool hexagon_cpu_has_work(CPUState *cs)
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 19697b4..a219a7f 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -337,7 +337,7 @@
*/
#define fGEN_TCG_PRED_LOAD(GET_EA, PRED, SIZE, SIGN) \
do { \
- TCGv LSB = tcg_temp_local_new(); \
+ TCGv LSB = tcg_temp_new(); \
TCGLabel *label = gen_new_label(); \
tcg_gen_movi_tl(EA, 0); \
PRED; \
@@ -397,7 +397,7 @@
/* Predicated loads into a register pair */
#define fGEN_TCG_PRED_LOAD_PAIR(GET_EA, PRED) \
do { \
- TCGv LSB = tcg_temp_local_new(); \
+ TCGv LSB = tcg_temp_new(); \
TCGLabel *label = gen_new_label(); \
tcg_gen_movi_tl(EA, 0); \
PRED; \
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 7e8ba17..dfc9071 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -26,18 +26,14 @@
## Helpers for gen_tcg_func
##
def gen_decl_ea_tcg(f, tag):
- if ('A_CONDEXEC' in hex_common.attribdict[tag] or
- 'A_LOAD' in hex_common.attribdict[tag]):
- f.write(" TCGv EA = tcg_temp_local_new();\n")
- else:
- f.write(" TCGv EA = tcg_temp_new();\n")
+ f.write(" TCGv EA = tcg_temp_new();\n")
def gen_free_ea_tcg(f):
f.write(" tcg_temp_free(EA);\n")
def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
regN="%s%sN" % (regtype,regid)
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
(regtype, regid))
if (regtype == "C"):
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
@@ -56,7 +52,7 @@
def genptr_decl_writable(f, tag, regtype, regid, regno):
regN="%s%sN" % (regtype,regid)
- f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \
+ f.write(" TCGv %s%sV = tcg_temp_new();\n" % \
(regtype, regid))
if (regtype == "C"):
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
@@ -73,7 +69,7 @@
regN="%s%sN" % (regtype,regid)
if (regtype == "R"):
if (regid in {"ss", "tt"}):
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
(regtype, regid))
f.write(" const int %s = insn->regno[%d];\n" % \
(regN, regno))
@@ -96,14 +92,14 @@
print("Bad register parse: ", regtype, regid)
elif (regtype == "C"):
if (regid == "ss"):
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
(regtype, regid))
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
(regN, regno))
elif (regid == "dd"):
genptr_decl_pair_writable(f, tag, regtype, regid, regno)
elif (regid == "s"):
- f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \
+ f.write(" TCGv %s%sV = tcg_temp_new();\n" % \
(regtype, regid))
f.write(" const int %s%sN = insn->regno[%d] + HEX_REG_SA0;\n" % \
(regtype, regid, regno))
@@ -575,7 +571,7 @@
## We produce:
## static void generate_A2_add(DisasContext *ctx)
## {
-## TCGv RdV = tcg_temp_local_new();
+## TCGv RdV = tcg_temp_new();
## const int RdN = insn->regno[0];
## TCGv RsV = hex_gpr[insn->regno[1]];
## TCGv RtV = hex_gpr[insn->regno[2]];
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 90db990..591461b 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -706,7 +706,7 @@
TCGCond cond, int pc_off)
{
TCGv next_PC;
- TCGv lsb = tcg_temp_local_new();
+ TCGv lsb = tcg_temp_new();
TCGLabel *skip = gen_new_label();
tcg_gen_andi_tl(lsb, pred, 1);
gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb);
@@ -720,7 +720,7 @@
static void gen_endloop0(DisasContext *ctx)
{
- TCGv lpcfg = tcg_temp_local_new();
+ TCGv lpcfg = tcg_temp_new();
GET_USR_FIELD(USR_LPCFG, lpcfg);
@@ -852,7 +852,7 @@
/* Bidirectional shift right with saturation */
static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
{
- TCGv shift_amt = tcg_temp_local_new();
+ TCGv shift_amt = tcg_temp_new();
TCGLabel *positive = gen_new_label();
TCGLabel *done = gen_new_label();
@@ -876,7 +876,7 @@
/* Bidirectional shift left with saturation */
static void gen_asl_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
{
- TCGv shift_amt = tcg_temp_local_new();
+ TCGv shift_amt = tcg_temp_new();
TCGLabel *positive = gen_new_label();
TCGLabel *done = gen_new_label();
@@ -918,7 +918,7 @@
intptr_t dstoff;
if (is_predicated) {
- TCGv cancelled = tcg_temp_local_new();
+ TCGv cancelled = tcg_temp_new();
label_end = gen_new_label();
/* Don't do anything if the slot was cancelled */
@@ -959,7 +959,7 @@
intptr_t dstoff;
if (is_predicated) {
- TCGv cancelled = tcg_temp_local_new();
+ TCGv cancelled = tcg_temp_new();
label_end = gen_new_label();
/* Don't do anything if the slot was cancelled */
@@ -1164,10 +1164,10 @@
/* Implements the fADDSAT64 macro in TCG */
void gen_add_sat_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 sum = tcg_temp_local_new_i64();
+ TCGv_i64 sum = tcg_temp_new_i64();
TCGv_i64 xor = tcg_temp_new_i64();
TCGv_i64 cond1 = tcg_temp_new_i64();
- TCGv_i64 cond2 = tcg_temp_local_new_i64();
+ TCGv_i64 cond2 = tcg_temp_new_i64();
TCGv_i64 cond3 = tcg_temp_new_i64();
TCGv_i64 mask = tcg_constant_i64(0x8000000000000000ULL);
TCGv_i64 max_pos = tcg_constant_i64(0x7FFFFFFFFFFFFFFFLL);
diff --git a/target/hexagon/idef-parser/README.rst b/target/hexagon/idef-parser/README.rst
index ff6d141..c230fec 100644
--- a/target/hexagon/idef-parser/README.rst
+++ b/target/hexagon/idef-parser/README.rst
@@ -294,9 +294,9 @@
::
- int var1; -> TCGv_i32 var1 = tcg_temp_local_new_i32();
+ int var1; -> TCGv_i32 var1 = tcg_temp_new_i32();
- int var2 = 0; -> TCGv_i32 var1 = tcg_temp_local_new_i32();
+ int var2 = 0; -> TCGv_i32 var1 = tcg_temp_new_i32();
tcg_gen_movi_i32(j, ((int64_t) 0ULL));
which are later automatically freed at the end of the function they're declared
diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
index 8110686..3025040 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -307,26 +307,6 @@
return rvalue;
}
-HexValue gen_tmp_local(Context *c,
- YYLTYPE *locp,
- unsigned bit_width,
- HexSignedness signedness)
-{
- HexValue rvalue;
- assert(bit_width == 32 || bit_width == 64);
- memset(&rvalue, 0, sizeof(HexValue));
- rvalue.type = TEMP;
- rvalue.bit_width = bit_width;
- rvalue.signedness = signedness;
- rvalue.is_dotnew = false;
- rvalue.is_manual = false;
- rvalue.tmp.index = c->inst.tmp_count;
- OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count,
- " = tcg_temp_local_new_i", &bit_width, "();\n");
- c->inst.tmp_count++;
- return rvalue;
-}
-
HexValue gen_tmp_value(Context *c,
YYLTYPE *locp,
const char *value,
@@ -554,7 +534,7 @@
new_var.signedness = signedness;
EMIT_HEAD(c, "TCGv_%s %s", bit_suffix, varid->var.name->str);
- EMIT_HEAD(c, " = tcg_temp_local_new_%s();\n", bit_suffix);
+ EMIT_HEAD(c, " = tcg_temp_new_%s();\n", bit_suffix);
g_array_append_val(c->inst.allocated, new_var);
}
@@ -2161,8 +2141,8 @@
assert_signedness(c, locp, sat->signedness);
unsigned_str = (sat->signedness == UNSIGNED) ? "u" : "";
- res = gen_tmp_local(c, locp, value->bit_width, sat->signedness);
- ovfl = gen_tmp_local(c, locp, 32, sat->signedness);
+ res = gen_tmp(c, locp, value->bit_width, sat->signedness);
+ ovfl = gen_tmp(c, locp, 32, sat->signedness);
OUT(c, locp, "gen_sat", unsigned_str, "_", bit_suffix, "_ovfl(");
OUT(c, locp, &ovfl, ", ", &res, ", ", value, ", ", &width->imm.value,
");\n");
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 75f28e0..381fdaa 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -539,7 +539,7 @@
tcg_temp_free(cancelled);
}
{
- TCGv address = tcg_temp_local_new();
+ TCGv address = tcg_temp_new();
tcg_gen_mov_tl(address, hex_store_addr[slot_num]);
/*
@@ -962,7 +962,7 @@
.disas_log = hexagon_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 55c1902..11022f9 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -26,7 +26,7 @@
#include "qemu/module.h"
#include "exec/exec-all.h"
#include "fpu/softfloat.h"
-
+#include "tcg/tcg.h"
static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
{
@@ -48,8 +48,10 @@
{
HPPACPU *cpu = HPPA_CPU(cs);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+
#ifdef CONFIG_USER_ONLY
- cpu->env.iaoq_f = tb_pc(tb);
+ cpu->env.iaoq_f = tb->pc;
cpu->env.iaoq_b = tb->cs_base;
#else
/* Recover the IAOQ values from the GVA + PRIV. */
@@ -59,7 +61,7 @@
int32_t diff = cs_base;
cpu->env.iasq_f = iasq_f;
- cpu->env.iaoq_f = (tb_pc(tb) & ~iasq_f) + priv;
+ cpu->env.iaoq_f = (tb->pc & ~iasq_f) + priv;
if (diff) {
cpu->env.iaoq_b = cpu->env.iaoq_f + diff;
}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 981f8ee..cee9609 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -35,7 +35,6 @@
#undef TCGv
#undef tcg_temp_new
#undef tcg_global_mem_new
-#undef tcg_temp_local_new
#undef tcg_temp_free
#if TARGET_LONG_BITS == 64
@@ -59,7 +58,6 @@
#define tcg_temp_new tcg_temp_new_i64
#define tcg_global_mem_new tcg_global_mem_new_i64
-#define tcg_temp_local_new tcg_temp_local_new_i64
#define tcg_temp_free tcg_temp_free_i64
#define tcg_gen_movi_reg tcg_gen_movi_i64
@@ -155,7 +153,6 @@
#define TCGv_reg TCGv_i32
#define tcg_temp_new tcg_temp_new_i32
#define tcg_global_mem_new tcg_global_mem_new_i32
-#define tcg_temp_local_new tcg_temp_local_new_i32
#define tcg_temp_free tcg_temp_free_i32
#define tcg_gen_movi_reg tcg_gen_movi_i32
@@ -4359,7 +4356,7 @@
.disas_log = hppa_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h
index f579b16..abad52a 100644
--- a/target/i386/cpu-param.h
+++ b/target/i386/cpu-param.h
@@ -25,8 +25,4 @@
#define TARGET_PAGE_BITS 12
#define NB_MMU_MODES 5
-#ifndef CONFIG_USER_ONLY
-# define TARGET_TB_PCREL 1
-#endif
-
#endif
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 4bad3d4..f3fbb0b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -31,11 +31,11 @@
#include "qapi/error.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/qmp/qerror.h"
-#include "qapi/qapi-commands-machine-target.h"
#include "standard-headers/asm-x86/kvm_para.h"
#include "hw/qdev-properties.h"
#include "hw/i386/topology.h"
#ifndef CONFIG_USER_ONLY
+#include "qapi/qapi-commands-machine-target.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
#include "hw/i386/sgx-epc.h"
@@ -4843,40 +4843,6 @@
visit_type_strList(v, "unavailable-features", &result, errp);
}
-/* Check for missing features that may prevent the CPU class from
- * running using the current machine and accelerator.
- */
-static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
- strList **list)
-{
- strList **tail = list;
- X86CPU *xc;
- Error *err = NULL;
-
- if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
- QAPI_LIST_APPEND(tail, g_strdup("kvm"));
- return;
- }
-
- xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
-
- x86_cpu_expand_features(xc, &err);
- if (err) {
- /* Errors at x86_cpu_expand_features should never happen,
- * but in case it does, just report the model as not
- * runnable at all using the "type" property.
- */
- QAPI_LIST_APPEND(tail, g_strdup("type"));
- error_free(err);
- }
-
- x86_cpu_filter_features(xc, false);
-
- x86_cpu_list_feature_names(xc->filtered_features, tail);
-
- object_unref(OBJECT(xc));
-}
-
/* Print all cpuid feature names in featureset
*/
static void listflags(GList *features)
@@ -5005,6 +4971,42 @@
g_list_free(names);
}
+#ifndef CONFIG_USER_ONLY
+
+/* Check for missing features that may prevent the CPU class from
+ * running using the current machine and accelerator.
+ */
+static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
+ strList **list)
+{
+ strList **tail = list;
+ X86CPU *xc;
+ Error *err = NULL;
+
+ if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
+ QAPI_LIST_APPEND(tail, g_strdup("kvm"));
+ return;
+ }
+
+ xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
+
+ x86_cpu_expand_features(xc, &err);
+ if (err) {
+ /* Errors at x86_cpu_expand_features should never happen,
+ * but in case it does, just report the model as not
+ * runnable at all using the "type" property.
+ */
+ QAPI_LIST_APPEND(tail, g_strdup("type"));
+ error_free(err);
+ }
+
+ x86_cpu_filter_features(xc, false);
+
+ x86_cpu_list_feature_names(xc->filtered_features, tail);
+
+ object_unref(OBJECT(xc));
+}
+
static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
@@ -5045,6 +5047,8 @@
return cpu_list;
}
+#endif /* !CONFIG_USER_ONLY */
+
uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
{
@@ -6534,6 +6538,11 @@
static bool ht_warned;
unsigned requested_lbr_fmt;
+ /* Use pc-relative instructions in system-mode */
+#ifndef CONFIG_USER_ONLY
+ cs->tcg_cflags |= CF_PCREL;
+#endif
+
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
error_setg(errp, "apic-id property was not initialized properly");
return;
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 0ac2da0..8857444 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -520,7 +520,7 @@
}
/* Per x86_restore_state_to_opc. */
- if (TARGET_TB_PCREL) {
+ if (cs->tcg_cflags & CF_PCREL) {
return (env->eip & TARGET_PAGE_MASK) | data[0];
} else {
return data[0] - env->segs[R_CS].base;
diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
index 55bd119..e87f90d 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -64,7 +64,7 @@
int flags;
inout->gaddr = addr;
- flags = probe_access_full(inout->env, addr, MMU_DATA_STORE,
+ flags = probe_access_full(inout->env, addr, 0, MMU_DATA_STORE,
inout->ptw_idx, true, &inout->haddr, &full, 0);
if (unlikely(flags & TLB_INVALID_MASK)) {
@@ -428,7 +428,7 @@
CPUTLBEntryFull *full;
int flags, nested_page_size;
- flags = probe_access_full(env, paddr, access_type,
+ flags = probe_access_full(env, paddr, 0, access_type,
MMU_NESTED_IDX, true,
&pte_trans.haddr, &full, 0);
if (unlikely(flags & TLB_INVALID_MASK)) {
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 79ac590..b942c30 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -49,10 +49,10 @@
static void x86_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- /* The instruction pointer is always up to date with TARGET_TB_PCREL. */
- if (!TARGET_TB_PCREL) {
+ /* The instruction pointer is always up to date with CF_PCREL. */
+ if (!(tb_cflags(tb) & CF_PCREL)) {
CPUX86State *env = cs->env_ptr;
- env->eip = tb_pc(tb) - tb->cs_base;
+ env->eip = tb->pc - tb->cs_base;
}
}
@@ -64,7 +64,7 @@
CPUX86State *env = &cpu->env;
int cc_op = data[1];
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(tb) & CF_PCREL) {
env->eip = (env->eip & TARGET_PAGE_MASK) | data[0];
} else {
env->eip = data[0] - tb->cs_base;
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 9d9392b..defbc43 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -545,7 +545,7 @@
static void gen_update_eip_cur(DisasContext *s)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
} else {
tcg_gen_movi_tl(cpu_eip, s->base.pc_next - s->cs_base);
@@ -556,7 +556,7 @@
static void gen_update_eip_next(DisasContext *s)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
} else {
tcg_gen_movi_tl(cpu_eip, s->pc - s->cs_base);
@@ -588,7 +588,7 @@
if (CODE64(s)) {
return tcg_constant_i32(-1);
}
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
TCGv_i32 ret = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(ret, cpu_eip);
tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
@@ -601,7 +601,7 @@
static TCGv eip_next_tl(DisasContext *s)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
TCGv ret = tcg_temp_new();
tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
return ret;
@@ -613,7 +613,7 @@
static TCGv eip_cur_tl(DisasContext *s)
{
assert(s->pc_save != -1);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
TCGv ret = tcg_temp_new();
tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
return ret;
@@ -1830,7 +1830,7 @@
tcg_temp_free_i32(t0);
tcg_temp_free_i32(t1);
- /* The CC_OP value is no longer predictable. */
+ /* The CC_OP value is no longer predictable. */
set_cc_op(s, CC_OP_DYNAMIC);
}
@@ -1923,7 +1923,7 @@
gen_op_ld_v(s, ot, s->T0, s->A0);
else
gen_op_mov_v_reg(s, ot, s->T0, op1);
-
+
if (is_right) {
switch (ot) {
case MO_8:
@@ -2319,7 +2319,7 @@
ea = cpu_regs[a.base];
}
if (!ea) {
- if (TARGET_TB_PCREL && a.base == -2) {
+ if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) {
/* With cpu_eip ~= pc_save, the expression is pc-relative. */
tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
} else {
@@ -2867,7 +2867,7 @@
if (!CODE64(s)) {
if (ot == MO_16) {
mask = 0xffff;
- if (TARGET_TB_PCREL && CODE32(s)) {
+ if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) {
use_goto_tb = false;
}
} else {
@@ -2879,7 +2879,7 @@
gen_update_cc_op(s);
set_cc_op(s, CC_OP_DYNAMIC);
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
/*
* If we can prove the branch does not leave the page and we have
@@ -2896,13 +2896,13 @@
translator_use_goto_tb(&s->base, new_eip + s->cs_base)) {
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
- if (!TARGET_TB_PCREL) {
+ if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
tcg_gen_movi_tl(cpu_eip, new_eip);
}
tcg_gen_exit_tb(s->base.tb, tb_num);
s->base.is_jmp = DISAS_NORETURN;
} else {
- if (!TARGET_TB_PCREL) {
+ if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
tcg_gen_movi_tl(cpu_eip, new_eip);
}
if (s->jmp_opt) {
@@ -3426,13 +3426,10 @@
if (mod == 3) {
goto illegal_op;
}
- a0 = tcg_temp_local_new();
- t0 = tcg_temp_local_new();
+ a0 = s->A0;
+ t0 = s->T0;
label1 = gen_new_label();
- tcg_gen_mov_tl(a0, s->A0);
- tcg_gen_mov_tl(t0, s->T0);
-
gen_set_label(label1);
t1 = tcg_temp_new();
t2 = tcg_temp_new();
@@ -3444,9 +3441,7 @@
tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
tcg_temp_free(t2);
- tcg_temp_free(a0);
tcg_gen_neg_tl(s->T0, t0);
- tcg_temp_free(t0);
} else {
tcg_gen_neg_tl(s->T0, s->T0);
if (mod != 3) {
@@ -6248,13 +6243,13 @@
#endif
{
TCGLabel *label1;
- TCGv t0, t1, t2, a0;
+ TCGv t0, t1, t2;
if (!PE(s) || VM86(s))
goto illegal_op;
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
- t2 = tcg_temp_local_new();
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ t2 = tcg_temp_new();
ot = MO_16;
modrm = x86_ldub_code(env, s);
reg = (modrm >> 3) & 7;
@@ -6263,11 +6258,8 @@
if (mod != 3) {
gen_lea_modrm(env, s, modrm);
gen_op_ld_v(s, ot, t0, s->A0);
- a0 = tcg_temp_local_new();
- tcg_gen_mov_tl(a0, s->A0);
} else {
gen_op_mov_v_reg(s, ot, t0, rm);
- a0 = NULL;
}
gen_op_mov_v_reg(s, ot, t1, reg);
tcg_gen_andi_tl(s->tmp0, t0, 3);
@@ -6280,8 +6272,7 @@
tcg_gen_movi_tl(t2, CC_Z);
gen_set_label(label1);
if (mod != 3) {
- gen_op_st_v(s, ot, t0, a0);
- tcg_temp_free(a0);
+ gen_op_st_v(s, ot, t0, s->A0);
} else {
gen_op_mov_reg_v(s, ot, rm, t0);
}
@@ -6304,7 +6295,7 @@
modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | REX_R(s);
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
- t0 = tcg_temp_local_new();
+ t0 = tcg_temp_new();
gen_update_cc_op(s);
if (b == 0x102) {
gen_helper_lar(t0, cpu_env, s->T0);
@@ -7052,7 +7043,7 @@
dc->tmp2_i32 = tcg_temp_new_i32();
dc->tmp3_i32 = tcg_temp_new_i32();
dc->tmp4 = tcg_temp_new();
- dc->cc_srcT = tcg_temp_local_new();
+ dc->cc_srcT = tcg_temp_new();
}
static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
@@ -7065,7 +7056,7 @@
target_ulong pc_arg = dc->base.pc_next;
dc->prev_insn_end = tcg_last_op();
- if (TARGET_TB_PCREL) {
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
pc_arg -= dc->cs_base;
pc_arg &= ~TARGET_PAGE_MASK;
}
@@ -7158,7 +7149,7 @@
};
/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 290ab4d..d6513f2 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -12,12 +12,12 @@
#include "qemu/module.h"
#include "sysemu/qtest.h"
#include "exec/exec-all.h"
-#include "qapi/qapi-commands-machine-target.h"
#include "cpu.h"
#include "internals.h"
#include "fpu/softfloat-helpers.h"
#include "cpu-csr.h"
#include "sysemu/reset.h"
+#include "tcg/tcg.h"
const char * const regnames[32] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -321,7 +321,8 @@
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = &cpu->env;
- env->pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ env->pc = tb->pc;
}
static void loongarch_restore_state_to_opc(CPUState *cs,
@@ -599,7 +600,7 @@
oc = object_class_by_name(cpu_model);
if (!oc) {
- g_autofree char *typename
+ g_autofree char *typename
= g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
oc = object_class_by_name(typename);
if (!oc) {
@@ -748,29 +749,3 @@
};
DEFINE_TYPES(loongarch_cpu_type_infos)
-
-static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
- const char *typename = object_class_get_name(oc);
-
- info->name = g_strndup(typename,
- strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU));
- info->q_typename = g_strdup(typename);
-
- QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
-
- list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
- g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
- g_slist_free(list);
-
- return cpu_list;
-}
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
new file mode 100644
index 0000000..6c25957
--- /dev/null
+++ b/target/loongarch/loongarch-qmp-cmds.c
@@ -0,0 +1,37 @@
+/*
+ * QEMU LoongArch CPU (monitor definitions)
+ *
+ * SPDX-FileCopyrightText: 2021 Loongson Technology Corporation Limited
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu.h"
+
+static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **cpu_list = user_data;
+ CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
+ const char *typename = object_class_get_name(oc);
+
+ info->name = g_strndup(typename,
+ strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU));
+ info->q_typename = g_strdup(typename);
+
+ QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
+
+ list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
+ g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
+ g_slist_free(list);
+
+ return cpu_list;
+}
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
index 6906339..9293a8a 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -16,6 +16,7 @@
loongarch_softmmu_ss = ss.source_set()
loongarch_softmmu_ss.add(files(
+ 'loongarch-qmp-cmds.c',
'machine.c',
'tlb_helper.c',
'constant_timer.c',
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 72a6275..2a43ab0 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -245,7 +245,7 @@
.disas_log = loongarch_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 31178c3..157c2cb 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -6393,7 +6393,7 @@
.disas_log = m68k_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index a2d2f5c..03c2c4d 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -30,6 +30,7 @@
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "fpu/softfloat-helpers.h"
+#include "tcg/tcg.h"
static const struct {
const char *name;
@@ -97,7 +98,8 @@
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- cpu->env.pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ cpu->env.pc = tb->pc;
cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
}
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 974f21e..037a652 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1849,7 +1849,7 @@
.disas_log = mb_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/mips/tcg/exception.c b/target/mips/tcg/exception.c
index 96e6117..da49a93 100644
--- a/target/mips/tcg/exception.c
+++ b/target/mips/tcg/exception.c
@@ -82,7 +82,8 @@
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;
- env->active_tc.PC = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ env->active_tc.PC = tb->pc;
env->hflags &= ~MIPS_HFLAG_BMASK;
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
}
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
index 812c111..faf6d67 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -1017,8 +1017,8 @@
static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
uint32_t reg1, uint32_t reg2, bool eva)
{
- TCGv taddr = tcg_temp_local_new();
- TCGv lladdr = tcg_temp_local_new();
+ TCGv taddr = tcg_temp_new();
+ TCGv lladdr = tcg_temp_new();
TCGv_i64 tval = tcg_temp_new_i64();
TCGv_i64 llval = tcg_temp_new_i64();
TCGv_i64 val = tcg_temp_new_i64();
diff --git a/target/mips/tcg/sysemu/special_helper.c b/target/mips/tcg/sysemu/special_helper.c
index 3c5f35c..93276f7 100644
--- a/target/mips/tcg/sysemu/special_helper.c
+++ b/target/mips/tcg/sysemu/special_helper.c
@@ -94,7 +94,7 @@
CPUMIPSState *env = &cpu->env;
if ((env->hflags & MIPS_HFLAG_BMASK) != 0
- && env->active_tc.PC != tb_pc(tb)) {
+ && !(cs->tcg_cflags & CF_PCREL) && env->active_tc.PC != tb->pc) {
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
env->hflags &= ~MIPS_HFLAG_BMASK;
return true;
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index aa12bb7..8cad3d1 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -2400,7 +2400,7 @@
switch (opc) {
case OPC_ADDI:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -2434,7 +2434,7 @@
#if defined(TARGET_MIPS64)
case OPC_DADDI:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -2630,7 +2630,7 @@
switch (opc) {
case OPC_ADD:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -2666,7 +2666,7 @@
break;
case OPC_SUB:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -2707,7 +2707,7 @@
#if defined(TARGET_MIPS64)
case OPC_DADD:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -2741,7 +2741,7 @@
break;
case OPC_DSUB:
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
TCGLabel *l1 = gen_new_label();
@@ -3759,26 +3759,8 @@
return;
}
- switch (opc) {
- case OPC_MULT_G_2E:
- case OPC_MULT_G_2F:
- case OPC_MULTU_G_2E:
- case OPC_MULTU_G_2F:
-#if defined(TARGET_MIPS64)
- case OPC_DMULT_G_2E:
- case OPC_DMULT_G_2F:
- case OPC_DMULTU_G_2E:
- case OPC_DMULTU_G_2F:
-#endif
- t0 = tcg_temp_new();
- t1 = tcg_temp_new();
- break;
- default:
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
- break;
- }
-
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
@@ -3955,21 +3937,10 @@
TCGCond cond;
opc = MASK_LMMI(ctx->opcode);
- switch (opc) {
- case OPC_ADD_CP2:
- case OPC_SUB_CP2:
- case OPC_DADD_CP2:
- case OPC_DSUB_CP2:
- t0 = tcg_temp_local_new_i64();
- t1 = tcg_temp_local_new_i64();
- break;
- default:
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- break;
- }
-
check_cp1_enabled(ctx);
+
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
gen_load_fpr64(ctx, t0, rs);
gen_load_fpr64(ctx, t1, rt);
@@ -8650,7 +8621,7 @@
int u, int sel, int h)
{
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
@@ -8878,7 +8849,7 @@
int u, int sel, int h)
{
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
gen_load_gpr(t0, rt);
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
@@ -11409,7 +11380,7 @@
case OPC_ALNV_PS:
check_ps(ctx);
{
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
TCGv_i32 fp = tcg_temp_new_i32();
TCGv_i32 fph = tcg_temp_new_i32();
TCGLabel *l1 = gen_new_label();
@@ -16159,7 +16130,7 @@
.disas_log = mips_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 7aee65a..140bc31 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -1037,7 +1037,7 @@
.disas_log = nios2_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 4c11a1f..0ce4f79 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -22,6 +22,7 @@
#include "qemu/qemu-print.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "tcg/tcg.h"
static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
{
@@ -43,7 +44,8 @@
{
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
- cpu->env.pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ cpu->env.pc = tb->pc;
}
static void openrisc_restore_state_to_opc(CPUState *cs,
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 2f3d7c5..b8cd8e0 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1705,7 +1705,7 @@
.disas_log = openrisc_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 0fbd8b7..9666f54 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -31,6 +31,8 @@
OBJECT_DECLARE_CPU_TYPE(PowerPCCPU, PowerPCCPUClass, POWERPC_CPU)
+ObjectClass *ppc_cpu_class_by_name(const char *name);
+
typedef struct CPUArchState CPUPPCState;
typedef struct ppc_tb_t ppc_tb_t;
typedef struct ppc_dcr_t ppc_dcr_t;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index abee71d..d62ffe8 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -40,7 +40,6 @@
#include "qemu/cutils.h"
#include "disas/capstone.h"
#include "fpu/softfloat.h"
-#include "qapi/qapi-commands-machine-target.h"
#include "helper_regs.h"
#include "internal.h"
@@ -6841,7 +6840,7 @@
return NULL;
}
-static ObjectClass *ppc_cpu_class_by_name(const char *name)
+ObjectClass *ppc_cpu_class_by_name(const char *name)
{
char *cpu_model, *typename;
ObjectClass *oc;
@@ -6981,51 +6980,6 @@
#endif
}
-static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **first = user_data;
- const char *typename;
- CpuDefinitionInfo *info;
-
- typename = object_class_get_name(oc);
- info = g_malloc0(sizeof(*info));
- info->name = g_strndup(typename,
- strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
-
- QAPI_LIST_PREPEND(*first, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
- int i;
-
- list = object_class_get_list(TYPE_POWERPC_CPU, false);
- g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
- g_slist_free(list);
-
- for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
- PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
- ObjectClass *oc;
- CpuDefinitionInfo *info;
-
- oc = ppc_cpu_class_by_name(alias->model);
- if (oc == NULL) {
- continue;
- }
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(alias->alias);
- info->q_typename = g_strdup(object_class_get_name(oc));
-
- QAPI_LIST_PREPEND(cpu_list, info);
- }
-
- return cpu_list;
-}
-
static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
diff --git a/target/ppc/meson.build b/target/ppc/meson.build
index 79beaff..7929de8 100644
--- a/target/ppc/meson.build
+++ b/target/ppc/meson.build
@@ -39,7 +39,7 @@
'machine.c',
'mmu-hash32.c',
'mmu_common.c',
- 'monitor.c',
+ 'ppc-qmp-cmds.c',
))
ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files(
'mmu_helper.c',
diff --git a/target/ppc/monitor.c b/target/ppc/ppc-qmp-cmds.c
similarity index 77%
rename from target/ppc/monitor.c
rename to target/ppc/ppc-qmp-cmds.c
index 8250b13..36e5b5e 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/ppc-qmp-cmds.c
@@ -1,5 +1,5 @@
/*
- * QEMU monitor
+ * QEMU PPC (monitor definitions)
*
* Copyright (c) 2003-2004 Fabrice Bellard
*
@@ -28,6 +28,9 @@
#include "qemu/ctype.h"
#include "monitor/hmp-target.h"
#include "monitor/hmp.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu-models.h"
+#include "cpu-qom.h"
static target_long monitor_get_ccr(Monitor *mon, const struct MonitorDef *md,
int val)
@@ -172,3 +175,48 @@
return -EINVAL;
}
+
+static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **first = user_data;
+ const char *typename;
+ CpuDefinitionInfo *info;
+
+ typename = object_class_get_name(oc);
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strndup(typename,
+ strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
+
+ QAPI_LIST_PREPEND(*first, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
+ int i;
+
+ list = object_class_get_list(TYPE_POWERPC_CPU, false);
+ g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
+ g_slist_free(list);
+
+ for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+ PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+ ObjectClass *oc;
+ CpuDefinitionInfo *info;
+
+ oc = ppc_cpu_class_by_name(alias->model);
+ if (oc == NULL) {
+ continue;
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(alias->alias);
+ info->q_typename = g_strdup(object_class_get_name(oc));
+
+ QAPI_LIST_PREPEND(cpu_list, info);
+ }
+
+ return cpu_list;
+}
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 1c17d5a..2956021 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4415,7 +4415,7 @@
TCGv target;
if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
- target = tcg_temp_local_new();
+ target = tcg_temp_new();
if (type == BCOND_CTR) {
tcg_gen_mov_tl(target, cpu_ctr);
} else if (type == BCOND_TAR) {
@@ -5594,8 +5594,8 @@
{
TCGv t0, t1;
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
switch (opc3 & 0x0D) {
case 0x05:
@@ -7707,7 +7707,7 @@
.disas_log = ppc_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/ppc/translate/spe-impl.c.inc b/target/ppc/translate/spe-impl.c.inc
index 2e6e799..bd8963d 100644
--- a/target/ppc/translate/spe-impl.c.inc
+++ b/target/ppc/translate/spe-impl.c.inc
@@ -168,7 +168,7 @@
{
TCGLabel *l1 = gen_new_label();
TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
/* No error here: 6 bits are used */
tcg_gen_andi_i32(t0, arg2, 0x3F);
@@ -185,7 +185,7 @@
{
TCGLabel *l1 = gen_new_label();
TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
/* No error here: 6 bits are used */
tcg_gen_andi_i32(t0, arg2, 0x3F);
@@ -202,7 +202,7 @@
{
TCGLabel *l1 = gen_new_label();
TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
/* No error here: 6 bits are used */
tcg_gen_andi_i32(t0, arg2, 0x3F);
@@ -378,7 +378,7 @@
TCGLabel *l2 = gen_new_label();
TCGLabel *l3 = gen_new_label();
TCGLabel *l4 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc
index 7741f2e..2dd17ab 100644
--- a/target/ppc/translate/vmx-impl.c.inc
+++ b/target/ppc/translate/vmx-impl.c.inc
@@ -1508,8 +1508,8 @@
REQUIRE_INSNS_FLAGS2(ctx, ISA310);
REQUIRE_VECTOR(ctx);
- vra = tcg_temp_local_new_i64();
- vrb = tcg_temp_local_new_i64();
+ vra = tcg_temp_new_i64();
+ vrb = tcg_temp_new_i64();
gt = gen_new_label();
lt = gen_new_label();
done = gen_new_label();
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 93b52b8..9eb748a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -34,6 +34,7 @@
#include "fpu/softfloat-helpers.h"
#include "sysemu/kvm.h"
#include "kvm_riscv.h"
+#include "tcg/tcg.h"
/* RISC-V CPU definitions */
@@ -533,10 +534,12 @@
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+
if (xl == MXL_RV32) {
- env->pc = (int32_t)tb_pc(tb);
+ env->pc = (int32_t) tb->pc;
} else {
- env->pc = tb_pc(tb);
+ env->pc = tb->pc;
}
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 772f9d7..f9d5d10 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1309,7 +1309,7 @@
.disas_log = riscv_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 219ef28..67452e3 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -44,7 +44,8 @@
{
RXCPU *cpu = RX_CPU(cs);
- cpu->env.pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ cpu->env.pc = tb->pc;
}
static void rx_restore_state_to_opc(CPUState *cs,
diff --git a/target/rx/translate.c b/target/rx/translate.c
index 87a3f54..af23876 100644
--- a/target/rx/translate.c
+++ b/target/rx/translate.c
@@ -2363,7 +2363,7 @@
.disas_log = rx_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index e51a0db..6835c26 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -145,7 +145,7 @@
int mmu_idx, bool nonfault,
void **phost, uintptr_t ra)
{
- int flags = probe_access_flags(env, addr, access_type, mmu_idx,
+ int flags = probe_access_flags(env, addr, 0, access_type, mmu_idx,
nonfault, phost, ra);
if (unlikely(flags & TLB_INVALID_MASK)) {
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index faa6f73..811049e 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -6619,7 +6619,7 @@
.disas_log = s390x_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index f0934b2..61769ff 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -26,6 +26,7 @@
#include "migration/vmstate.h"
#include "exec/exec-all.h"
#include "fpu/softfloat-helpers.h"
+#include "tcg/tcg.h"
static void superh_cpu_set_pc(CPUState *cs, vaddr value)
{
@@ -46,7 +47,8 @@
{
SuperHCPU *cpu = SUPERH_CPU(cs);
- cpu->env.pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ cpu->env.pc = tb->pc;
cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
}
@@ -73,7 +75,7 @@
CPUSH4State *env = &cpu->env;
if ((env->flags & (TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND))
- && env->pc != tb_pc(tb)) {
+ && !(cs->tcg_cflags & CF_PCREL) && env->pc != tb->pc) {
env->pc -= 2;
env->flags &= ~(TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND);
return true;
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 7db3468..2356302 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -2374,7 +2374,7 @@
.disas_log = sh4_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 1734ef8..e329a7a 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -25,6 +25,7 @@
#include "exec/exec-all.h"
#include "hw/qdev-properties.h"
#include "qapi/visitor.h"
+#include "tcg/tcg.h"
//#define DEBUG_FEATURES
@@ -707,7 +708,8 @@
{
SPARCCPU *cpu = SPARC_CPU(cs);
- cpu->env.pc = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ cpu->env.pc = tb->pc;
cpu->env.npc = tb->cs_base;
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 150aeec..3b0044a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5904,7 +5904,7 @@
.disas_log = sparc_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc = {};
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 594cd1e..d0a9272 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -55,7 +55,8 @@
TriCoreCPU *cpu = TRICORE_CPU(cs);
CPUTriCoreState *env = &cpu->env;
- env->PC = tb_pc(tb);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ env->PC = tb->pc;
}
static void tricore_restore_state_to_opc(CPUState *cs,
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 7ac34ef..176ea96 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -8881,7 +8881,7 @@
};
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext ctx;
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 77bcd71..4af0650 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -307,7 +307,7 @@
static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
{
if (!dc->sar_m32_allocated) {
- dc->sar_m32 = tcg_temp_local_new_i32();
+ dc->sar_m32 = tcg_temp_new_i32();
dc->sar_m32_allocated = true;
}
tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
@@ -1074,10 +1074,10 @@
if (i == 0 || arg_copy[i].resource != resource) {
resource = arg_copy[i].resource;
if (arg_copy[i].arg->num_bits <= 32) {
- temp = tcg_temp_local_new_i32();
+ temp = tcg_temp_new_i32();
tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
} else if (arg_copy[i].arg->num_bits <= 64) {
- temp = tcg_temp_local_new_i64();
+ temp = tcg_temp_new_i64();
tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
} else {
g_assert_not_reached();
@@ -1187,7 +1187,7 @@
DisasContext *dc = container_of(dcbase, DisasContext, base);
if (dc->icount) {
- dc->next_icount = tcg_temp_local_new_i32();
+ dc->next_icount = tcg_temp_new_i32();
}
}
@@ -1279,7 +1279,7 @@
.disas_log = xtensa_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
target_ulong pc, void *host_pc)
{
DisasContext dc = {};
@@ -2273,8 +2273,8 @@
static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
const uint32_t par[])
{
- TCGv_i32 tmp = tcg_temp_local_new_i32();
- TCGv_i32 addr = tcg_temp_local_new_i32();
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ TCGv_i32 addr = tcg_temp_new_i32();
MemOp mop;
tcg_gen_mov_i32(tmp, arg[0].in);
@@ -2303,8 +2303,8 @@
const uint32_t par[])
{
TCGv_i32 prev = tcg_temp_new_i32();
- TCGv_i32 addr = tcg_temp_local_new_i32();
- TCGv_i32 res = tcg_temp_local_new_i32();
+ TCGv_i32 addr = tcg_temp_new_i32();
+ TCGv_i32 res = tcg_temp_new_i32();
TCGLabel *label = gen_new_label();
MemOp mop;
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 763bca9..ce05989 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -190,7 +190,7 @@
} else if (i->kind > ts->kind) {
if (i->kind == TEMP_GLOBAL) {
g = i;
- } else if (i->kind == TEMP_LOCAL) {
+ } else if (i->kind == TEMP_TB) {
l = i;
}
}
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index aacedd3..291a65c 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -116,8 +116,8 @@
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -137,8 +137,8 @@
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -157,9 +157,9 @@
TCGv_ptr a0, a1, a2;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -180,10 +180,10 @@
TCGv_ptr a0, a1, a2, a3;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
- a3 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
+ a3 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -206,11 +206,11 @@
TCGv_ptr a0, a1, a2, a3, a4;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
- a3 = tcg_temp_new_ptr();
- a4 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
+ a3 = tcg_temp_ebb_new_ptr();
+ a4 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -236,8 +236,8 @@
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -257,9 +257,9 @@
TCGv_ptr a0, a1, a2;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -282,10 +282,10 @@
TCGv_ptr a0, a1, a2, a3;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
- a3 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
+ a3 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -310,11 +310,11 @@
TCGv_ptr a0, a1, a2, a3, a4;
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
- a0 = tcg_temp_new_ptr();
- a1 = tcg_temp_new_ptr();
- a2 = tcg_temp_new_ptr();
- a3 = tcg_temp_new_ptr();
- a4 = tcg_temp_new_ptr();
+ a0 = tcg_temp_ebb_new_ptr();
+ a1 = tcg_temp_ebb_new_ptr();
+ a2 = tcg_temp_ebb_new_ptr();
+ a3 = tcg_temp_ebb_new_ptr();
+ a4 = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(a0, cpu_env, dofs);
tcg_gen_addi_ptr(a1, cpu_env, aofs);
@@ -575,16 +575,16 @@
be simple enough. */
if (TCG_TARGET_REG_BITS == 64
&& (vece != MO_32 || !check_size_impl(oprsz, 4))) {
- t_64 = tcg_temp_new_i64();
+ t_64 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(t_64, in_32);
tcg_gen_dup_i64(vece, t_64, t_64);
} else {
- t_32 = tcg_temp_new_i32();
+ t_32 = tcg_temp_ebb_new_i32();
tcg_gen_dup_i32(vece, t_32, in_32);
}
} else if (in_64) {
/* We are given a 64-bit variable input. */
- t_64 = tcg_temp_new_i64();
+ t_64 = tcg_temp_ebb_new_i64();
tcg_gen_dup_i64(vece, t_64, in_64);
} else {
/* We are given a constant input. */
@@ -619,7 +619,7 @@
}
/* Otherwise implement out of line. */
- t_ptr = tcg_temp_new_ptr();
+ t_ptr = tcg_temp_ebb_new_ptr();
tcg_gen_addi_ptr(t_ptr, cpu_env, dofs);
/*
@@ -629,13 +629,13 @@
* stores through to memset.
*/
if (oprsz == maxsz && vece == MO_8) {
- TCGv_ptr t_size = tcg_const_ptr(oprsz);
+ TCGv_ptr t_size = tcg_constant_ptr(oprsz);
TCGv_i32 t_val;
if (in_32) {
t_val = in_32;
} else if (in_64) {
- t_val = tcg_temp_new_i32();
+ t_val = tcg_temp_ebb_new_i32();
tcg_gen_extrl_i64_i32(t_val, in_64);
} else {
t_val = tcg_constant_i32(in_c);
@@ -645,7 +645,6 @@
if (in_64) {
tcg_temp_free_i32(t_val);
}
- tcg_temp_free_ptr(t_size);
tcg_temp_free_ptr(t_ptr);
return;
}
@@ -670,7 +669,7 @@
if (in_32) {
fns[vece](t_ptr, t_desc, in_32);
} else if (in_64) {
- t_32 = tcg_temp_new_i32();
+ t_32 = tcg_temp_ebb_new_i32();
tcg_gen_extrl_i64_i32(t_32, in_64);
fns[vece](t_ptr, t_desc, t_32);
tcg_temp_free_i32(t_32);
@@ -1734,7 +1733,7 @@
do_dup_store(type, dofs, oprsz, maxsz, t_vec);
tcg_temp_free_vec(t_vec);
} else if (vece <= MO_32) {
- TCGv_i32 in = tcg_temp_new_i32();
+ TCGv_i32 in = tcg_temp_ebb_new_i32();
switch (vece) {
case MO_8:
tcg_gen_ld8u_i32(in, cpu_env, aofs);
@@ -1749,7 +1748,7 @@
do_dup(vece, dofs, oprsz, maxsz, in, NULL, 0);
tcg_temp_free_i32(in);
} else {
- TCGv_i64 in = tcg_temp_new_i64();
+ TCGv_i64 in = tcg_temp_ebb_new_i64();
tcg_gen_ld_i64(in, cpu_env, aofs);
do_dup(vece, dofs, oprsz, maxsz, NULL, in, 0);
tcg_temp_free_i64(in);
@@ -1768,8 +1767,8 @@
}
tcg_temp_free_vec(in);
} else {
- TCGv_i64 in0 = tcg_temp_new_i64();
- TCGv_i64 in1 = tcg_temp_new_i64();
+ TCGv_i64 in0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 in1 = tcg_temp_ebb_new_i64();
tcg_gen_ld_i64(in0, cpu_env, aofs);
tcg_gen_ld_i64(in1, cpu_env, aofs + 8);
@@ -1814,7 +1813,7 @@
int j;
for (j = 0; j < 4; ++j) {
- in[j] = tcg_temp_new_i64();
+ in[j] = tcg_temp_ebb_new_i64();
tcg_gen_ld_i64(in[j], cpu_env, aofs + j * 8);
}
for (i = (aofs == dofs) * 32; i < oprsz; i += 32) {
@@ -1859,9 +1858,9 @@
the 64-bit operation. */
static void gen_addv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
tcg_gen_andc_i64(t1, a, m);
tcg_gen_andc_i64(t2, b, m);
@@ -1884,9 +1883,9 @@
void tcg_gen_vec_add8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 m = tcg_constant_i32((int32_t)dup_const(MO_8, 0x80));
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
- TCGv_i32 t3 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
tcg_gen_andc_i32(t1, a, m);
tcg_gen_andc_i32(t2, b, m);
@@ -1908,8 +1907,8 @@
void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t1, a, ~0xffff);
tcg_gen_add_i32(t2, a, b);
@@ -1922,8 +1921,8 @@
void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t1, a, ~0xffffffffull);
tcg_gen_add_i64(t2, a, b);
@@ -2042,9 +2041,9 @@
Compare gen_addv_mask above. */
static void gen_subv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
tcg_gen_or_i64(t1, a, m);
tcg_gen_andc_i64(t2, b, m);
@@ -2067,9 +2066,9 @@
void tcg_gen_vec_sub8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 m = tcg_constant_i32((int32_t)dup_const(MO_8, 0x80));
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
- TCGv_i32 t3 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
tcg_gen_or_i32(t1, a, m);
tcg_gen_andc_i32(t2, b, m);
@@ -2091,8 +2090,8 @@
void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t1, b, ~0xffff);
tcg_gen_sub_i32(t2, a, b);
@@ -2105,8 +2104,8 @@
void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t1, b, ~0xffffffffull);
tcg_gen_sub_i64(t2, a, b);
@@ -2467,8 +2466,8 @@
Compare gen_subv_mask above. */
static void gen_negv_mask(TCGv_i64 d, TCGv_i64 b, TCGv_i64 m)
{
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
tcg_gen_andc_i64(t3, m, b);
tcg_gen_andc_i64(t2, b, m);
@@ -2493,8 +2492,8 @@
void tcg_gen_vec_neg32_i64(TCGv_i64 d, TCGv_i64 b)
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t1, b, ~0xffffffffull);
tcg_gen_neg_i64(t2, b);
@@ -2539,7 +2538,7 @@
static void gen_absv_mask(TCGv_i64 d, TCGv_i64 b, unsigned vece)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
int nbit = 8 << vece;
/* Create -1 for each negative element. */
@@ -2748,7 +2747,7 @@
void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
{
- TCGv_i64 tmp = tcg_temp_new_i64();
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
tcg_gen_dup_i64(vece, tmp, c);
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ands);
tcg_temp_free_i64(tmp);
@@ -2772,7 +2771,7 @@
void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
{
- TCGv_i64 tmp = tcg_temp_new_i64();
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
tcg_gen_dup_i64(vece, tmp, c);
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_xors);
tcg_temp_free_i64(tmp);
@@ -2796,7 +2795,7 @@
void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
{
- TCGv_i64 tmp = tcg_temp_new_i64();
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
tcg_gen_dup_i64(vece, tmp, c);
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ors);
tcg_temp_free_i64(tmp);
@@ -2943,7 +2942,7 @@
{
uint64_t s_mask = dup_const(MO_8, 0x80 >> c);
uint64_t c_mask = dup_const(MO_8, 0xff >> c);
- TCGv_i64 s = tcg_temp_new_i64();
+ TCGv_i64 s = tcg_temp_ebb_new_i64();
tcg_gen_shri_i64(d, a, c);
tcg_gen_andi_i64(s, d, s_mask); /* isolate (shifted) sign bit */
@@ -2957,7 +2956,7 @@
{
uint64_t s_mask = dup_const(MO_16, 0x8000 >> c);
uint64_t c_mask = dup_const(MO_16, 0xffff >> c);
- TCGv_i64 s = tcg_temp_new_i64();
+ TCGv_i64 s = tcg_temp_ebb_new_i64();
tcg_gen_shri_i64(d, a, c);
tcg_gen_andi_i64(s, d, s_mask); /* isolate (shifted) sign bit */
@@ -2971,7 +2970,7 @@
{
uint32_t s_mask = dup_const(MO_8, 0x80 >> c);
uint32_t c_mask = dup_const(MO_8, 0xff >> c);
- TCGv_i32 s = tcg_temp_new_i32();
+ TCGv_i32 s = tcg_temp_ebb_new_i32();
tcg_gen_shri_i32(d, a, c);
tcg_gen_andi_i32(s, d, s_mask); /* isolate (shifted) sign bit */
@@ -2985,7 +2984,7 @@
{
uint32_t s_mask = dup_const(MO_16, 0x8000 >> c);
uint32_t c_mask = dup_const(MO_16, 0xffff >> c);
- TCGv_i32 s = tcg_temp_new_i32();
+ TCGv_i32 s = tcg_temp_ebb_new_i32();
tcg_gen_shri_i32(d, a, c);
tcg_gen_andi_i32(s, d, s_mask); /* isolate (shifted) sign bit */
@@ -3179,7 +3178,7 @@
TCGv_vec v_shift = tcg_temp_new_vec(type);
if (vece == MO_64) {
- TCGv_i64 sh64 = tcg_temp_new_i64();
+ TCGv_i64 sh64 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(sh64, shift);
tcg_gen_dup_i64_vec(MO_64, v_shift, sh64);
tcg_temp_free_i64(sh64);
@@ -3220,14 +3219,14 @@
if (vece == MO_32 && check_size_impl(oprsz, 4)) {
expand_2s_i32(dofs, aofs, oprsz, shift, false, g->fni4);
} else if (vece == MO_64 && check_size_impl(oprsz, 8)) {
- TCGv_i64 sh64 = tcg_temp_new_i64();
+ TCGv_i64 sh64 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(sh64, shift);
expand_2s_i64(dofs, aofs, oprsz, sh64, false, g->fni8);
tcg_temp_free_i64(sh64);
} else {
- TCGv_ptr a0 = tcg_temp_new_ptr();
- TCGv_ptr a1 = tcg_temp_new_ptr();
- TCGv_i32 desc = tcg_temp_new_i32();
+ TCGv_ptr a0 = tcg_temp_ebb_new_ptr();
+ TCGv_ptr a1 = tcg_temp_ebb_new_ptr();
+ TCGv_i32 desc = tcg_temp_ebb_new_i32();
tcg_gen_shli_i32(desc, shift, SIMD_DATA_SHIFT);
tcg_gen_ori_i32(desc, desc, simd_desc(oprsz, maxsz, 0));
@@ -3359,7 +3358,7 @@
static void tcg_gen_shl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t, b, 31);
tcg_gen_shl_i32(d, a, t);
@@ -3368,7 +3367,7 @@
static void tcg_gen_shl_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t, b, 63);
tcg_gen_shl_i64(d, a, t);
@@ -3422,7 +3421,7 @@
static void tcg_gen_shr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t, b, 31);
tcg_gen_shr_i32(d, a, t);
@@ -3431,7 +3430,7 @@
static void tcg_gen_shr_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t, b, 63);
tcg_gen_shr_i64(d, a, t);
@@ -3485,7 +3484,7 @@
static void tcg_gen_sar_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t, b, 31);
tcg_gen_sar_i32(d, a, t);
@@ -3494,7 +3493,7 @@
static void tcg_gen_sar_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t, b, 63);
tcg_gen_sar_i64(d, a, t);
@@ -3548,7 +3547,7 @@
static void tcg_gen_rotl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t, b, 31);
tcg_gen_rotl_i32(d, a, t);
@@ -3557,7 +3556,7 @@
static void tcg_gen_rotl_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t, b, 63);
tcg_gen_rotl_i64(d, a, t);
@@ -3607,7 +3606,7 @@
static void tcg_gen_rotr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_andi_i32(t, b, 31);
tcg_gen_rotr_i32(d, a, t);
@@ -3616,7 +3615,7 @@
static void tcg_gen_rotr_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_andi_i64(t, b, 63);
tcg_gen_rotr_i64(d, a, t);
@@ -3657,8 +3656,8 @@
static void expand_cmp_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs,
uint32_t oprsz, TCGCond cond)
{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
uint32_t i;
for (i = 0; i < oprsz; i += 4) {
@@ -3675,8 +3674,8 @@
static void expand_cmp_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs,
uint32_t oprsz, TCGCond cond)
{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
uint32_t i;
for (i = 0; i < oprsz; i += 8) {
@@ -3822,7 +3821,7 @@
static void tcg_gen_bitsel_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_and_i64(t, b, a);
tcg_gen_andc_i64(d, c, a);
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index c581ae7..f2269a1 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -264,7 +264,7 @@
if (TCG_TARGET_HAS_div_i32) {
tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div2_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_sari_i32(t0, arg1, 31);
tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
tcg_temp_free_i32(t0);
@@ -278,13 +278,13 @@
if (TCG_TARGET_HAS_rem_i32) {
tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
tcg_gen_mul_i32(t0, t0, arg2);
tcg_gen_sub_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
} else if (TCG_TARGET_HAS_div2_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_sari_i32(t0, arg1, 31);
tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
tcg_temp_free_i32(t0);
@@ -298,7 +298,7 @@
if (TCG_TARGET_HAS_div_i32) {
tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div2_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_movi_i32(t0, 0);
tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
tcg_temp_free_i32(t0);
@@ -312,13 +312,13 @@
if (TCG_TARGET_HAS_rem_i32) {
tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
tcg_gen_mul_i32(t0, t0, arg2);
tcg_gen_sub_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
} else if (TCG_TARGET_HAS_div2_i32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_movi_i32(t0, 0);
tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
tcg_temp_free_i32(t0);
@@ -332,7 +332,7 @@
if (TCG_TARGET_HAS_andc_i32) {
tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_not_i32(t0, arg2);
tcg_gen_and_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
@@ -374,7 +374,7 @@
if (TCG_TARGET_HAS_orc_i32) {
tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_not_i32(t0, arg2);
tcg_gen_or_i32(ret, arg1, t0);
tcg_temp_free_i32(t0);
@@ -386,8 +386,8 @@
if (TCG_TARGET_HAS_clz_i32) {
tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_clz_i64) {
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(t1, arg1);
tcg_gen_extu_i32_i64(t2, arg2);
tcg_gen_addi_i64(t2, t2, 32);
@@ -411,8 +411,8 @@
if (TCG_TARGET_HAS_ctz_i32) {
tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_ctz_i64) {
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(t1, arg1);
tcg_gen_extu_i32_i64(t2, arg2);
tcg_gen_ctz_i64(t1, t1, t2);
@@ -423,7 +423,7 @@
|| TCG_TARGET_HAS_ctpop_i64
|| TCG_TARGET_HAS_clz_i32
|| TCG_TARGET_HAS_clz_i64) {
- TCGv_i32 z, t = tcg_temp_new_i32();
+ TCGv_i32 z, t = tcg_temp_ebb_new_i32();
if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
tcg_gen_subi_i32(t, arg1, 1);
@@ -448,7 +448,7 @@
{
if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
/* This equivalence has the advantage of not requiring a fixup. */
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_subi_i32(t, arg1, 1);
tcg_gen_andc_i32(t, t, arg1);
tcg_gen_ctpop_i32(ret, t);
@@ -461,7 +461,7 @@
void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
{
if (TCG_TARGET_HAS_clz_i32) {
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_sari_i32(t, arg, 31);
tcg_gen_xor_i32(t, t, arg);
tcg_gen_clzi_i32(t, t, 32);
@@ -477,7 +477,7 @@
if (TCG_TARGET_HAS_ctpop_i32) {
tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
} else if (TCG_TARGET_HAS_ctpop_i64) {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(t, arg1);
tcg_gen_ctpop_i64(t, t);
tcg_gen_extrl_i64_i32(ret, t);
@@ -494,8 +494,8 @@
} else {
TCGv_i32 t0, t1;
- t0 = tcg_temp_new_i32();
- t1 = tcg_temp_new_i32();
+ t0 = tcg_temp_ebb_new_i32();
+ t1 = tcg_temp_ebb_new_i32();
tcg_gen_shl_i32(t0, arg1, arg2);
tcg_gen_subfi_i32(t1, 32, arg2);
tcg_gen_shr_i32(t1, arg1, t1);
@@ -515,8 +515,8 @@
tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
} else {
TCGv_i32 t0, t1;
- t0 = tcg_temp_new_i32();
- t1 = tcg_temp_new_i32();
+ t0 = tcg_temp_ebb_new_i32();
+ t1 = tcg_temp_ebb_new_i32();
tcg_gen_shli_i32(t0, arg1, arg2);
tcg_gen_shri_i32(t1, arg1, 32 - arg2);
tcg_gen_or_i32(ret, t0, t1);
@@ -532,8 +532,8 @@
} else {
TCGv_i32 t0, t1;
- t0 = tcg_temp_new_i32();
- t1 = tcg_temp_new_i32();
+ t0 = tcg_temp_ebb_new_i32();
+ t1 = tcg_temp_ebb_new_i32();
tcg_gen_shr_i32(t0, arg1, arg2);
tcg_gen_subfi_i32(t1, 32, arg2);
tcg_gen_shl_i32(t1, arg1, t1);
@@ -574,7 +574,7 @@
return;
}
- t1 = tcg_temp_new_i32();
+ t1 = tcg_temp_ebb_new_i32();
if (TCG_TARGET_HAS_extract2_i32) {
if (ofs + len == 32) {
@@ -801,7 +801,7 @@
} else if (TCG_TARGET_HAS_extract2_i32) {
tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_shri_i32(t0, al, ofs);
tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
tcg_temp_free_i32(t0);
@@ -818,8 +818,8 @@
} else if (TCG_TARGET_HAS_movcond_i32) {
tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
tcg_gen_setcond_i32(cond, t0, c1, c2);
tcg_gen_neg_i32(t0, t0);
tcg_gen_and_i32(t1, v1, t0);
@@ -836,8 +836,8 @@
if (TCG_TARGET_HAS_add2_i32) {
tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_concat_i32_i64(t0, al, ah);
tcg_gen_concat_i32_i64(t1, bl, bh);
tcg_gen_add_i64(t0, t0, t1);
@@ -853,8 +853,8 @@
if (TCG_TARGET_HAS_sub2_i32) {
tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_concat_i32_i64(t0, al, ah);
tcg_gen_concat_i32_i64(t1, bl, bh);
tcg_gen_sub_i64(t0, t0, t1);
@@ -869,14 +869,14 @@
if (TCG_TARGET_HAS_mulu2_i32) {
tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
} else if (TCG_TARGET_HAS_muluh_i32) {
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
tcg_gen_mov_i32(rl, t);
tcg_temp_free_i32(t);
} else if (TCG_TARGET_REG_BITS == 64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(t0, arg1);
tcg_gen_extu_i32_i64(t1, arg2);
tcg_gen_mul_i64(t0, t0, t1);
@@ -893,16 +893,16 @@
if (TCG_TARGET_HAS_muls2_i32) {
tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
} else if (TCG_TARGET_HAS_mulsh_i32) {
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
tcg_gen_mov_i32(rl, t);
tcg_temp_free_i32(t);
} else if (TCG_TARGET_REG_BITS == 32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
- TCGv_i32 t3 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
/* Adjust for negative inputs. */
tcg_gen_sari_i32(t2, arg1, 31);
@@ -917,8 +917,8 @@
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t3);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_ext_i32_i64(t0, arg1);
tcg_gen_ext_i32_i64(t1, arg2);
tcg_gen_mul_i64(t0, t0, t1);
@@ -931,9 +931,9 @@
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
{
if (TCG_TARGET_REG_BITS == 32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
/* Adjust for negative input for the signed arg1. */
tcg_gen_sari_i32(t2, arg1, 31);
@@ -944,8 +944,8 @@
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_ext_i32_i64(t0, arg1);
tcg_gen_extu_i32_i64(t1, arg2);
tcg_gen_mul_i64(t0, t0, t1);
@@ -1001,8 +1001,8 @@
if (TCG_TARGET_HAS_bswap16_i32) {
tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
tcg_gen_shri_i32(t0, arg, 8);
if (!(flags & TCG_BSWAP_IZ)) {
@@ -1030,8 +1030,8 @@
if (TCG_TARGET_HAS_bswap32_i32) {
tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
/* arg = abcd */
@@ -1078,7 +1078,7 @@
void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
{
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_sari_i32(t, a, 31);
tcg_gen_xor_i32(ret, a, t);
@@ -1241,8 +1241,8 @@
TCGv_i64 t0;
TCGv_i32 t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i32();
+ t0 = tcg_temp_ebb_new_i64();
+ t1 = tcg_temp_ebb_new_i32();
tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
TCGV_LOW(arg1), TCGV_LOW(arg2));
@@ -1423,7 +1423,7 @@
tcg_gen_extract2_i32(TCGV_HIGH(ret),
TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
} else {
- TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
TCGV_HIGH(arg1), c, 32 - c);
@@ -1557,7 +1557,7 @@
if (TCG_TARGET_HAS_div_i64) {
tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div2_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_sari_i64(t0, arg1, 63);
tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
tcg_temp_free_i64(t0);
@@ -1571,13 +1571,13 @@
if (TCG_TARGET_HAS_rem_i64) {
tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
tcg_gen_mul_i64(t0, t0, arg2);
tcg_gen_sub_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
} else if (TCG_TARGET_HAS_div2_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_sari_i64(t0, arg1, 63);
tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
tcg_temp_free_i64(t0);
@@ -1591,7 +1591,7 @@
if (TCG_TARGET_HAS_div_i64) {
tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div2_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_movi_i64(t0, 0);
tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
tcg_temp_free_i64(t0);
@@ -1605,13 +1605,13 @@
if (TCG_TARGET_HAS_rem_i64) {
tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_div_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
tcg_gen_mul_i64(t0, t0, arg2);
tcg_gen_sub_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
} else if (TCG_TARGET_HAS_div2_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_movi_i64(t0, 0);
tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
tcg_temp_free_i64(t0);
@@ -1710,8 +1710,8 @@
} else if (TCG_TARGET_HAS_bswap16_i64) {
tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_shri_i64(t0, arg, 8);
if (!(flags & TCG_BSWAP_IZ)) {
@@ -1749,8 +1749,8 @@
} else if (TCG_TARGET_HAS_bswap32_i64) {
tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
/* arg = xxxxabcd */
@@ -1778,8 +1778,8 @@
{
if (TCG_TARGET_REG_BITS == 32) {
TCGv_i32 t0, t1;
- t0 = tcg_temp_new_i32();
- t1 = tcg_temp_new_i32();
+ t0 = tcg_temp_ebb_new_i32();
+ t1 = tcg_temp_ebb_new_i32();
tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
@@ -1790,9 +1790,9 @@
} else if (TCG_TARGET_HAS_bswap64_i64) {
tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
/* arg = abcdefgh */
tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
@@ -1822,8 +1822,8 @@
void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
{
uint64_t m = 0x0000ffff0000ffffull;
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
/* See include/qemu/bitops.h, hswap64. */
tcg_gen_rotli_i64(t1, arg, 32);
@@ -1863,7 +1863,7 @@
} else if (TCG_TARGET_HAS_andc_i64) {
tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_not_i64(t0, arg2);
tcg_gen_and_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
@@ -1917,7 +1917,7 @@
} else if (TCG_TARGET_HAS_orc_i64) {
tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_not_i64(t0, arg2);
tcg_gen_or_i64(ret, arg1, t0);
tcg_temp_free_i64(t0);
@@ -1938,7 +1938,7 @@
if (TCG_TARGET_REG_BITS == 32
&& TCG_TARGET_HAS_clz_i32
&& arg2 <= 0xffffffffu) {
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
tcg_gen_addi_i32(t, t, 32);
tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
@@ -1956,7 +1956,7 @@
if (TCG_TARGET_HAS_ctz_i64) {
tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
} else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
- TCGv_i64 z, t = tcg_temp_new_i64();
+ TCGv_i64 z, t = tcg_temp_ebb_new_i64();
if (TCG_TARGET_HAS_ctpop_i64) {
tcg_gen_subi_i64(t, arg1, 1);
@@ -1983,7 +1983,7 @@
if (TCG_TARGET_REG_BITS == 32
&& TCG_TARGET_HAS_ctz_i32
&& arg2 <= 0xffffffffu) {
- TCGv_i32 t32 = tcg_temp_new_i32();
+ TCGv_i32 t32 = tcg_temp_ebb_new_i32();
tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
tcg_gen_addi_i32(t32, t32, 32);
tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
@@ -1993,7 +1993,7 @@
&& TCG_TARGET_HAS_ctpop_i64
&& arg2 == 64) {
/* This equivalence has the advantage of not requiring a fixup. */
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_subi_i64(t, arg1, 1);
tcg_gen_andc_i64(t, t, arg1);
tcg_gen_ctpop_i64(ret, t);
@@ -2008,7 +2008,7 @@
void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
{
if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_sari_i64(t, arg, 63);
tcg_gen_xor_i64(t, t, arg);
tcg_gen_clzi_i64(t, t, 64);
@@ -2039,8 +2039,8 @@
tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
} else {
TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
+ t0 = tcg_temp_ebb_new_i64();
+ t1 = tcg_temp_ebb_new_i64();
tcg_gen_shl_i64(t0, arg1, arg2);
tcg_gen_subfi_i64(t1, 64, arg2);
tcg_gen_shr_i64(t1, arg1, t1);
@@ -2060,8 +2060,8 @@
tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
} else {
TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
+ t0 = tcg_temp_ebb_new_i64();
+ t1 = tcg_temp_ebb_new_i64();
tcg_gen_shli_i64(t0, arg1, arg2);
tcg_gen_shri_i64(t1, arg1, 64 - arg2);
tcg_gen_or_i64(ret, t0, t1);
@@ -2076,8 +2076,8 @@
tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
} else {
TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
+ t0 = tcg_temp_ebb_new_i64();
+ t1 = tcg_temp_ebb_new_i64();
tcg_gen_shr_i64(t0, arg1, arg2);
tcg_gen_subfi_i64(t1, 64, arg2);
tcg_gen_shl_i64(t1, arg1, t1);
@@ -2133,7 +2133,7 @@
}
}
- t1 = tcg_temp_new_i64();
+ t1 = tcg_temp_ebb_new_i64();
if (TCG_TARGET_HAS_extract2_i64) {
if (ofs + len == 64) {
@@ -2365,7 +2365,7 @@
tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
return;
} else if (len > 32) {
- TCGv_i32 t = tcg_temp_new_i32();
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
/* Extract the bits for the high word normally. */
tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
/* Shift the field down for the low part. */
@@ -2460,7 +2460,7 @@
} else if (TCG_TARGET_HAS_extract2_i64) {
tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_shri_i64(t0, al, ofs);
tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
tcg_temp_free_i64(t0);
@@ -2475,8 +2475,8 @@
} else if (cond == TCG_COND_NEVER) {
tcg_gen_mov_i64(ret, v2);
} else if (TCG_TARGET_REG_BITS == 32) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
TCGV_LOW(c1), TCGV_HIGH(c1),
TCGV_LOW(c2), TCGV_HIGH(c2), cond);
@@ -2503,8 +2503,8 @@
} else if (TCG_TARGET_HAS_movcond_i64) {
tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_setcond_i64(cond, t0, c1, c2);
tcg_gen_neg_i64(t0, t0);
tcg_gen_and_i64(t1, v1, t0);
@@ -2521,8 +2521,8 @@
if (TCG_TARGET_HAS_add2_i64) {
tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_add_i64(t0, al, bl);
tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
tcg_gen_add_i64(rh, ah, bh);
@@ -2539,8 +2539,8 @@
if (TCG_TARGET_HAS_sub2_i64) {
tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
tcg_gen_sub_i64(t0, al, bl);
tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
tcg_gen_sub_i64(rh, ah, bh);
@@ -2556,13 +2556,13 @@
if (TCG_TARGET_HAS_mulu2_i64) {
tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
} else if (TCG_TARGET_HAS_muluh_i64) {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
tcg_gen_mov_i64(rl, t);
tcg_temp_free_i64(t);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_mul_i64(t0, arg1, arg2);
gen_helper_muluh_i64(rh, arg1, arg2);
tcg_gen_mov_i64(rl, t0);
@@ -2575,16 +2575,16 @@
if (TCG_TARGET_HAS_muls2_i64) {
tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
} else if (TCG_TARGET_HAS_mulsh_i64) {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
tcg_gen_mov_i64(rl, t);
tcg_temp_free_i64(t);
} else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
/* Adjust for negative inputs. */
tcg_gen_sari_i64(t2, arg1, 63);
@@ -2599,7 +2599,7 @@
tcg_temp_free_i64(t2);
tcg_temp_free_i64(t3);
} else {
- TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
tcg_gen_mul_i64(t0, arg1, arg2);
gen_helper_mulsh_i64(rh, arg1, arg2);
tcg_gen_mov_i64(rl, t0);
@@ -2609,9 +2609,9 @@
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
/* Adjust for negative input for the signed arg1. */
tcg_gen_sari_i64(t2, arg1, 63);
@@ -2645,7 +2645,7 @@
void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
{
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_sari_i64(t, a, 63);
tcg_gen_xor_i64(ret, a, t);
@@ -2675,7 +2675,7 @@
tcg_gen_op2(INDEX_op_extrh_i64_i32,
tcgv_i32_arg(ret), tcgv_i64_arg(arg));
} else {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_shri_i64(t, arg, 32);
tcg_gen_mov_i32(ret, (TCGv_i32)t);
tcg_temp_free_i64(t);
@@ -2714,7 +2714,7 @@
return;
}
- tmp = tcg_temp_new_i64();
+ tmp = tcg_temp_ebb_new_i64();
/* These extensions are only needed for type correctness.
We may be able to do better given target specific information. */
tcg_gen_extu_i32_i64(tmp, high);
@@ -2826,7 +2826,7 @@
}
plugin_gen_disable_mem_helpers();
- ptr = tcg_temp_new_ptr();
+ ptr = tcg_temp_ebb_new_ptr();
gen_helper_lookup_tb_ptr(ptr, cpu_env);
tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
tcg_temp_free_ptr(ptr);
@@ -2987,7 +2987,7 @@
oi = make_memop_idx(memop, idx);
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
- swap = tcg_temp_new_i32();
+ swap = tcg_temp_ebb_new_i32();
switch (memop & MO_SIZE) {
case MO_16:
tcg_gen_bswap16_i32(swap, val, 0);
@@ -3082,7 +3082,7 @@
oi = make_memop_idx(memop, idx);
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
- swap = tcg_temp_new_i64();
+ swap = tcg_temp_ebb_new_i64();
switch (memop & MO_SIZE) {
case MO_16:
tcg_gen_bswap16_i64(swap, val, 0);
@@ -3224,7 +3224,7 @@
addr_p8 = tcg_temp_new();
if ((mop[0] ^ memop) & MO_BSWAP) {
- TCGv_i64 t = tcg_temp_new_i64();
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
tcg_gen_bswap64_i64(t, x);
gen_ldst_i64(INDEX_op_qemu_st_i64, t, addr, mop[0], idx);
@@ -3328,8 +3328,8 @@
void tcg_gen_nonatomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
TCGv_i32 newv, TCGArg idx, MemOp memop)
{
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);
@@ -3385,8 +3385,8 @@
return;
}
- t1 = tcg_temp_new_i64();
- t2 = tcg_temp_new_i64();
+ t1 = tcg_temp_ebb_new_i64();
+ t2 = tcg_temp_ebb_new_i64();
tcg_gen_ext_i64(t2, cmpv, memop & MO_SIZE);
@@ -3442,9 +3442,9 @@
tcg_gen_movi_i32(TCGV_HIGH(retv), 0);
}
} else {
- TCGv_i32 c32 = tcg_temp_new_i32();
- TCGv_i32 n32 = tcg_temp_new_i32();
- TCGv_i32 r32 = tcg_temp_new_i32();
+ TCGv_i32 c32 = tcg_temp_ebb_new_i32();
+ TCGv_i32 n32 = tcg_temp_ebb_new_i32();
+ TCGv_i32 r32 = tcg_temp_ebb_new_i32();
tcg_gen_extrl_i64_i32(c32, cmpv);
tcg_gen_extrl_i64_i32(n32, newv);
@@ -3476,10 +3476,10 @@
gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
} else {
- TCGv_i128 oldv = tcg_temp_new_i128();
- TCGv_i128 tmpv = tcg_temp_new_i128();
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i128 oldv = tcg_temp_ebb_new_i128();
+ TCGv_i128 tmpv = tcg_temp_ebb_new_i128();
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
TCGv_i64 z = tcg_constant_i64(0);
tcg_gen_qemu_ld_i128(oldv, addr, idx, memop);
@@ -3541,8 +3541,8 @@
TCGArg idx, MemOp memop, bool new_val,
void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
{
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
memop = tcg_canonicalize_memop(memop, 0, 0);
@@ -3579,8 +3579,8 @@
TCGArg idx, MemOp memop, bool new_val,
void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
{
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
memop = tcg_canonicalize_memop(memop, 1, 0);
@@ -3616,8 +3616,8 @@
tcg_gen_movi_i64(ret, 0);
#endif /* CONFIG_ATOMIC64 */
} else {
- TCGv_i32 v32 = tcg_temp_new_i32();
- TCGv_i32 r32 = tcg_temp_new_i32();
+ TCGv_i32 v32 = tcg_temp_ebb_new_i32();
+ TCGv_i32 r32 = tcg_temp_ebb_new_i32();
tcg_gen_extrl_i64_i32(v32, val);
do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 9822c65..5cccc06 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1254,66 +1254,69 @@
return ts;
}
-TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
+TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
{
TCGContext *s = tcg_ctx;
- TCGTempKind kind = temp_local ? TEMP_LOCAL : TEMP_NORMAL;
TCGTemp *ts;
- int idx, k;
+ int n;
- k = type + (temp_local ? TCG_TYPE_COUNT : 0);
- idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
- if (idx < TCG_MAX_TEMPS) {
- /* There is already an available temp with the right type. */
- clear_bit(idx, s->free_temps[k].l);
+ if (kind == TEMP_EBB) {
+ int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS);
- ts = &s->temps[idx];
- ts->temp_allocated = 1;
- tcg_debug_assert(ts->base_type == type);
- tcg_debug_assert(ts->kind == kind);
- } else {
- int i, n;
+ if (idx < TCG_MAX_TEMPS) {
+ /* There is already an available temp with the right type. */
+ clear_bit(idx, s->free_temps[type].l);
- switch (type) {
- case TCG_TYPE_I32:
- case TCG_TYPE_V64:
- case TCG_TYPE_V128:
- case TCG_TYPE_V256:
- n = 1;
- break;
- case TCG_TYPE_I64:
- n = 64 / TCG_TARGET_REG_BITS;
- break;
- case TCG_TYPE_I128:
- n = 128 / TCG_TARGET_REG_BITS;
- break;
- default:
- g_assert_not_reached();
+ ts = &s->temps[idx];
+ ts->temp_allocated = 1;
+ tcg_debug_assert(ts->base_type == type);
+ tcg_debug_assert(ts->kind == kind);
+ goto done;
}
+ } else {
+ tcg_debug_assert(kind == TEMP_TB);
+ }
- ts = tcg_temp_alloc(s);
- ts->base_type = type;
- ts->temp_allocated = 1;
- ts->kind = kind;
+ switch (type) {
+ case TCG_TYPE_I32:
+ case TCG_TYPE_V64:
+ case TCG_TYPE_V128:
+ case TCG_TYPE_V256:
+ n = 1;
+ break;
+ case TCG_TYPE_I64:
+ n = 64 / TCG_TARGET_REG_BITS;
+ break;
+ case TCG_TYPE_I128:
+ n = 128 / TCG_TARGET_REG_BITS;
+ break;
+ default:
+ g_assert_not_reached();
+ }
- if (n == 1) {
- ts->type = type;
- } else {
- ts->type = TCG_TYPE_REG;
+ ts = tcg_temp_alloc(s);
+ ts->base_type = type;
+ ts->temp_allocated = 1;
+ ts->kind = kind;
- for (i = 1; i < n; ++i) {
- TCGTemp *ts2 = tcg_temp_alloc(s);
+ if (n == 1) {
+ ts->type = type;
+ } else {
+ ts->type = TCG_TYPE_REG;
- tcg_debug_assert(ts2 == ts + i);
- ts2->base_type = type;
- ts2->type = TCG_TYPE_REG;
- ts2->temp_allocated = 1;
- ts2->temp_subindex = i;
- ts2->kind = kind;
- }
+ for (int i = 1; i < n; ++i) {
+ TCGTemp *ts2 = tcg_temp_alloc(s);
+
+ tcg_debug_assert(ts2 == ts + i);
+ ts2->base_type = type;
+ ts2->type = TCG_TYPE_REG;
+ ts2->temp_allocated = 1;
+ ts2->temp_subindex = i;
+ ts2->kind = kind;
}
}
+ done:
#if defined(CONFIG_DEBUG_TCG)
s->temps_in_use++;
#endif
@@ -1340,7 +1343,7 @@
}
#endif
- t = tcg_temp_new_internal(type, 0);
+ t = tcg_temp_new_internal(type, TEMP_EBB);
return temp_tcgv_vec(t);
}
@@ -1351,14 +1354,13 @@
tcg_debug_assert(t->temp_allocated != 0);
- t = tcg_temp_new_internal(t->base_type, 0);
+ t = tcg_temp_new_internal(t->base_type, TEMP_EBB);
return temp_tcgv_vec(t);
}
void tcg_temp_free_internal(TCGTemp *ts)
{
TCGContext *s = tcg_ctx;
- int k, idx;
switch (ts->kind) {
case TEMP_CONST:
@@ -1367,26 +1369,25 @@
* silently ignore free.
*/
return;
- case TEMP_NORMAL:
- case TEMP_LOCAL:
+ case TEMP_EBB:
+ case TEMP_TB:
break;
default:
g_assert_not_reached();
}
-#if defined(CONFIG_DEBUG_TCG)
- s->temps_in_use--;
- if (s->temps_in_use < 0) {
- fprintf(stderr, "More temporaries freed than allocated!\n");
- }
-#endif
-
tcg_debug_assert(ts->temp_allocated != 0);
ts->temp_allocated = 0;
- idx = temp_idx(ts);
- k = ts->base_type + (ts->kind == TEMP_NORMAL ? 0 : TCG_TYPE_COUNT);
- set_bit(idx, s->free_temps[k].l);
+#if defined(CONFIG_DEBUG_TCG)
+ assert(s->temps_in_use > 0);
+ s->temps_in_use--;
+#endif
+
+ if (ts->kind == TEMP_EBB) {
+ int idx = temp_idx(ts);
+ set_bit(idx, s->free_temps[ts->base_type].l);
+ }
}
TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
@@ -1474,22 +1475,6 @@
return t0;
}
-TCGv_i32 tcg_const_local_i32(int32_t val)
-{
- TCGv_i32 t0;
- t0 = tcg_temp_local_new_i32();
- tcg_gen_movi_i32(t0, val);
- return t0;
-}
-
-TCGv_i64 tcg_const_local_i64(int64_t val)
-{
- TCGv_i64 t0;
- t0 = tcg_temp_local_new_i64();
- tcg_gen_movi_i64(t0, val);
- return t0;
-}
-
#if defined(CONFIG_DEBUG_TCG)
void tcg_clear_temp_count(void)
{
@@ -1866,7 +1851,7 @@
case TCG_CALL_ARG_EXTEND_U:
case TCG_CALL_ARG_EXTEND_S:
{
- TCGv_i64 temp = tcg_temp_new_i64();
+ TCGv_i64 temp = tcg_temp_ebb_new_i64();
TCGv_i32 orig = temp_tcgv_i32(ts);
if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
@@ -1912,11 +1897,10 @@
break;
case TEMP_GLOBAL:
break;
- case TEMP_NORMAL:
case TEMP_EBB:
val = TEMP_VAL_DEAD;
/* fall through */
- case TEMP_LOCAL:
+ case TEMP_TB:
ts->mem_allocated = 0;
break;
default:
@@ -1938,13 +1922,10 @@
case TEMP_GLOBAL:
pstrcpy(buf, buf_size, ts->name);
break;
- case TEMP_LOCAL:
+ case TEMP_TB:
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
break;
case TEMP_EBB:
- snprintf(buf, buf_size, "ebb%d", idx - s->nb_globals);
- break;
- case TEMP_NORMAL:
snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
break;
case TEMP_CONST:
@@ -2637,9 +2618,10 @@
}
/* Reachable analysis : remove unreachable code. */
-static void reachable_code_pass(TCGContext *s)
+static void __attribute__((noinline))
+reachable_code_pass(TCGContext *s)
{
- TCGOp *op, *op_next;
+ TCGOp *op, *op_next, *op_prev;
bool dead = false;
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
@@ -2649,6 +2631,22 @@
switch (op->opc) {
case INDEX_op_set_label:
label = arg_label(op->args[0]);
+
+ /*
+ * Optimization can fold conditional branches to unconditional.
+ * If we find a label which is preceded by an unconditional
+ * branch to next, remove the branch. We couldn't do this when
+ * processing the branch because any dead code between the branch
+ * and label had not yet been removed.
+ */
+ op_prev = QTAILQ_PREV(op, link);
+ if (op_prev->opc == INDEX_op_br &&
+ label == arg_label(op_prev->args[0])) {
+ tcg_op_remove(s, op_prev);
+ /* Fall through means insns become live again. */
+ dead = false;
+ }
+
if (label->refs == 0) {
/*
* While there is an occasional backward branch, virtually
@@ -2662,21 +2660,6 @@
/* Once we see a label, insns become live again. */
dead = false;
remove = false;
-
- /*
- * Optimization can fold conditional branches to unconditional.
- * If we find a label with one reference which is preceded by
- * an unconditional branch to it, remove both. This needed to
- * wait until the dead code in between them was removed.
- */
- if (label->refs == 1) {
- TCGOp *op_prev = QTAILQ_PREV(op, link);
- if (op_prev->opc == INDEX_op_br &&
- label == arg_label(op_prev->args[0])) {
- tcg_op_remove(s, op_prev);
- remove = true;
- }
- }
}
break;
@@ -2759,10 +2742,9 @@
switch (ts->kind) {
case TEMP_FIXED:
case TEMP_GLOBAL:
- case TEMP_LOCAL:
+ case TEMP_TB:
state = TS_DEAD | TS_MEM;
break;
- case TEMP_NORMAL:
case TEMP_EBB:
case TEMP_CONST:
state = TS_DEAD;
@@ -2804,16 +2786,13 @@
int state;
switch (ts->kind) {
- case TEMP_LOCAL:
+ case TEMP_TB:
state = ts->state;
ts->state = state | TS_MEM;
if (state != TS_DEAD) {
continue;
}
break;
- case TEMP_NORMAL:
- s->temps[i].state = TS_DEAD;
- break;
case TEMP_EBB:
case TEMP_CONST:
continue;
@@ -2857,10 +2836,80 @@
}
}
+/*
+ * Liveness analysis: Verify the lifetime of TEMP_TB, and reduce
+ * to TEMP_EBB, if possible.
+ */
+static void __attribute__((noinline))
+liveness_pass_0(TCGContext *s)
+{
+ void * const multiple_ebb = (void *)(uintptr_t)-1;
+ int nb_temps = s->nb_temps;
+ TCGOp *op, *ebb;
+
+ for (int i = s->nb_globals; i < nb_temps; ++i) {
+ s->temps[i].state_ptr = NULL;
+ }
+
+ /*
+ * Represent each EBB by the op at which it begins. In the case of
+ * the first EBB, this is the first op, otherwise it is a label.
+ * Collect the uses of each TEMP_TB: NULL for unused, EBB for use
+ * within a single EBB, else MULTIPLE_EBB.
+ */
+ ebb = QTAILQ_FIRST(&s->ops);
+ QTAILQ_FOREACH(op, &s->ops, link) {
+ const TCGOpDef *def;
+ int nb_oargs, nb_iargs;
+
+ switch (op->opc) {
+ case INDEX_op_set_label:
+ ebb = op;
+ continue;
+ case INDEX_op_discard:
+ continue;
+ case INDEX_op_call:
+ nb_oargs = TCGOP_CALLO(op);
+ nb_iargs = TCGOP_CALLI(op);
+ break;
+ default:
+ def = &tcg_op_defs[op->opc];
+ nb_oargs = def->nb_oargs;
+ nb_iargs = def->nb_iargs;
+ break;
+ }
+
+ for (int i = 0; i < nb_oargs + nb_iargs; ++i) {
+ TCGTemp *ts = arg_temp(op->args[i]);
+
+ if (ts->kind != TEMP_TB) {
+ continue;
+ }
+ if (ts->state_ptr == NULL) {
+ ts->state_ptr = ebb;
+ } else if (ts->state_ptr != ebb) {
+ ts->state_ptr = multiple_ebb;
+ }
+ }
+ }
+
+ /*
+ * For TEMP_TB that turned out not to be used beyond one EBB,
+ * reduce the liveness to TEMP_EBB.
+ */
+ for (int i = s->nb_globals; i < nb_temps; ++i) {
+ TCGTemp *ts = &s->temps[i];
+ if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) {
+ ts->kind = TEMP_EBB;
+ }
+ }
+}
+
/* Liveness analysis : update the opc_arg_life array to tell if a
given input arguments is dead. Instructions updating dead
temporaries are removed. */
-static void liveness_pass_1(TCGContext *s)
+static void __attribute__((noinline))
+liveness_pass_1(TCGContext *s)
{
int nb_globals = s->nb_globals;
int nb_temps = s->nb_temps;
@@ -3200,7 +3249,8 @@
}
/* Liveness analysis: Convert indirect regs to direct temporaries. */
-static bool liveness_pass_2(TCGContext *s)
+static bool __attribute__((noinline))
+liveness_pass_2(TCGContext *s)
{
int nb_globals = s->nb_globals;
int nb_temps, i;
@@ -3497,10 +3547,9 @@
case TEMP_FIXED:
return;
case TEMP_GLOBAL:
- case TEMP_LOCAL:
+ case TEMP_TB:
new_type = TEMP_VAL_MEM;
break;
- case TEMP_NORMAL:
case TEMP_EBB:
new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
break;
@@ -3785,10 +3834,9 @@
TCGTemp *ts = &s->temps[i];
switch (ts->kind) {
- case TEMP_LOCAL:
+ case TEMP_TB:
temp_save(s, ts, allocated_regs);
break;
- case TEMP_NORMAL:
case TEMP_EBB:
/* The liveness analysis already ensures that temps are dead.
Keep an tcg_debug_assert for safety. */
@@ -3822,12 +3870,9 @@
* Keep tcg_debug_asserts for safety.
*/
switch (ts->kind) {
- case TEMP_LOCAL:
+ case TEMP_TB:
tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
break;
- case TEMP_NORMAL:
- tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
- break;
case TEMP_EBB:
case TEMP_CONST:
break;
@@ -4870,6 +4915,7 @@
#endif
reachable_code_pass(s);
+ liveness_pass_0(s);
liveness_pass_1(s);
if (s->nb_indirects > 0) {