aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsd-user/elfload.c11
-rw-r--r--exec.c16
-rw-r--r--include/exec/cpu-all.h38
-rw-r--r--include/exec/cpu_ldst.h174
-rw-r--r--include/exec/cpu_ldst_template.h60
-rw-r--r--include/exec/cpu_ldst_useronly_template.h81
-rw-r--r--include/qemu/bswap.h11
-rw-r--r--linux-user/elfload.c7
-rw-r--r--linux-user/main.c6
-rw-r--r--linux-user/vm86.c57
-rw-r--r--monitor.c8
-rw-r--r--scripts/qapi-types.py8
-rw-r--r--target-alpha/cpu.h2
-rw-r--r--target-arm/cpu.h2
-rw-r--r--target-cris/cpu.h2
-rw-r--r--target-i386/cpu.h2
-rw-r--r--target-i386/seg_helper.c16
-rw-r--r--target-lm32/cpu.h2
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-microblaze/cpu.h2
-rw-r--r--target-mips/cpu.h1
-rw-r--r--target-mips/op_helper.c4
-rw-r--r--target-moxie/cpu.h2
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-s390x/cpu.h2
-rw-r--r--target-sh4/cpu.h1
-rw-r--r--target-sparc/cpu.h2
-rw-r--r--target-sparc/ldst_helper.c24
-rw-r--r--target-xtensa/cpu.h2
-rw-r--r--translate-all.c4
30 files changed, 242 insertions, 309 deletions
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 93fd9e4259..2bf57eb1fc 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -351,8 +351,10 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info *
_regs->gpr[1] = infop->start_stack;
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
- entry = ldq_raw(infop->entry) + infop->load_addr;
- toc = ldq_raw(infop->entry + 8) + infop->load_addr;
+ get_user_u64(entry, infop->entry);
+ entry += infop->load_addr;
+ get_user_u64(toc, infop->entry + 8);
+ toc += infop->load_addr;
_regs->gpr[2] = toc;
infop->entry = entry;
#endif
@@ -365,8 +367,9 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info *
get_user_ual(_regs->gpr[3], pos);
pos += sizeof(abi_ulong);
_regs->gpr[4] = pos;
- for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
- tmp = ldl(pos);
+ for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) {
+ get_user_ual(tmp, pos);
+ }
_regs->gpr[5] = pos;
}
diff --git a/exec.c b/exec.c
index 081818e6e8..410371d7b8 100644
--- a/exec.c
+++ b/exec.c
@@ -553,7 +553,6 @@ void cpu_exec_init(CPUArchState *env)
}
}
-#if defined(TARGET_HAS_ICE)
#if defined(CONFIG_USER_ONLY)
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
@@ -569,7 +568,6 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
}
}
#endif
-#endif /* TARGET_HAS_ICE */
#if defined(CONFIG_USER_ONLY)
void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
@@ -689,7 +687,6 @@ static inline bool cpu_watchpoint_address_matches(CPUWatchpoint *wp,
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
CPUBreakpoint **breakpoint)
{
-#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
bp = g_malloc(sizeof(*bp));
@@ -710,15 +707,11 @@ int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
*breakpoint = bp;
}
return 0;
-#else
- return -ENOSYS;
-#endif
}
/* Remove a specific breakpoint. */
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
{
-#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
@@ -728,27 +721,21 @@ int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
}
}
return -ENOENT;
-#else
- return -ENOSYS;
-#endif
}
/* Remove a specific breakpoint by reference. */
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint)
{
-#if defined(TARGET_HAS_ICE)
QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry);
breakpoint_invalidate(cpu, breakpoint->pc);
g_free(breakpoint);
-#endif
}
/* Remove all matching breakpoints. */
void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
{
-#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp, *next;
QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
@@ -756,14 +743,12 @@ void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
cpu_breakpoint_remove_by_ref(cpu, bp);
}
}
-#endif
}
/* enable or disable single step mode. EXCP_DEBUG is returned by the
CPU loop after each instruction */
void cpu_single_step(CPUState *cpu, int enabled)
{
-#if defined(TARGET_HAS_ICE)
if (cpu->singlestep_enabled != enabled) {
cpu->singlestep_enabled = enabled;
if (kvm_enabled()) {
@@ -775,7 +760,6 @@ void cpu_single_step(CPUState *cpu, int enabled)
tb_flush(env);
}
}
-#endif
}
void cpu_abort(CPUState *cpu, const char *fmt, ...)
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 5fdd2fee80..2c4828694b 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -115,43 +115,9 @@ static inline void tswap64s(uint64_t *s)
#define bswaptls(s) bswap64s(s)
#endif
-/* CPU memory access without any memory or io remapping */
-
-/*
- * the generic syntax for the memory accesses is:
- *
- * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
- *
- * store: st{type}{size}{endian}_{access_type}(ptr, val)
- *
- * type is:
- * (empty): integer access
- * f : float access
- *
- * sign is:
- * (empty): for floats or 32 bit size
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * endian is:
- * (empty): target cpu endianness or 8 bit access
- * r : reversed target cpu endianness (not implemented yet)
- * be : big endian (not implemented yet)
- * le : little endian (not implemented yet)
- *
- * access_type is:
- * raw : host memory access
- * user : user mode access using soft MMU
- * kernel : kernel mode access using soft MMU
+/* Target-endianness CPU memory access functions. These fit into the
+ * {ld,st}{type}{sign}{size}{endian}_p naming scheme described in bswap.h.
*/
-
-/* target-endianness CPU memory access functions */
#if defined(TARGET_WORDS_BIGENDIAN)
#define lduw_p(p) lduw_be_p(p)
#define ldsw_p(p) ldsw_be_p(p)
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index e5550e7175..0e825ea773 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -23,7 +23,26 @@
*
* Used by target op helpers.
*
- * MMU mode suffixes are defined in target cpu.h.
+ * The syntax for the accessors is:
+ *
+ * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr)
+ *
+ * store: cpu_st{sign}{size}_{mmusuffix}(env, ptr, val)
+ *
+ * sign is:
+ * (empty): for 32 and 64 bit sizes
+ * u : unsigned
+ * s : signed
+ *
+ * size is:
+ * b: 8 bits
+ * w: 16 bits
+ * l: 32 bits
+ * q: 64 bits
+ *
+ * mmusuffix is one of the generic suffixes "data" or "code", or
+ * (for softmmu configs) a target-specific MMU mode suffix as defined
+ * in target cpu.h.
*/
#ifndef CPU_LDST_H
#define CPU_LDST_H
@@ -53,112 +72,43 @@
h2g_nocheck(x); \
})
-#define saddr(x) g2h(x)
-#define laddr(x) g2h(x)
-
-#else /* !CONFIG_USER_ONLY */
-/* NOTE: we use double casts if pointers and target_ulong have
- different sizes */
-#define saddr(x) (uint8_t *)(intptr_t)(x)
-#define laddr(x) (uint8_t *)(intptr_t)(x)
#endif
-#define ldub_raw(p) ldub_p(laddr((p)))
-#define ldsb_raw(p) ldsb_p(laddr((p)))
-#define lduw_raw(p) lduw_p(laddr((p)))
-#define ldsw_raw(p) ldsw_p(laddr((p)))
-#define ldl_raw(p) ldl_p(laddr((p)))
-#define ldq_raw(p) ldq_p(laddr((p)))
-#define ldfl_raw(p) ldfl_p(laddr((p)))
-#define ldfq_raw(p) ldfq_p(laddr((p)))
-#define stb_raw(p, v) stb_p(saddr((p)), v)
-#define stw_raw(p, v) stw_p(saddr((p)), v)
-#define stl_raw(p, v) stl_p(saddr((p)), v)
-#define stq_raw(p, v) stq_p(saddr((p)), v)
-#define stfl_raw(p, v) stfl_p(saddr((p)), v)
-#define stfq_raw(p, v) stfq_p(saddr((p)), v)
+#if defined(CONFIG_USER_ONLY)
+/* In user-only mode we provide only the _code and _data accessors. */
-#if defined(CONFIG_USER_ONLY)
+#define MEMSUFFIX _data
+#define DATA_SIZE 1
+#include "exec/cpu_ldst_useronly_template.h"
-/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
-
-#define cpu_ldub_code(env1, p) ldub_raw(p)
-#define cpu_ldsb_code(env1, p) ldsb_raw(p)
-#define cpu_lduw_code(env1, p) lduw_raw(p)
-#define cpu_ldsw_code(env1, p) ldsw_raw(p)
-#define cpu_ldl_code(env1, p) ldl_raw(p)
-#define cpu_ldq_code(env1, p) ldq_raw(p)
-
-#define cpu_ldub_data(env, addr) ldub_raw(addr)
-#define cpu_lduw_data(env, addr) lduw_raw(addr)
-#define cpu_ldsw_data(env, addr) ldsw_raw(addr)
-#define cpu_ldl_data(env, addr) ldl_raw(addr)
-#define cpu_ldq_data(env, addr) ldq_raw(addr)
-
-#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
-#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
-#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
-#define cpu_stq_data(env, addr, data) stq_raw(addr, data)
-
-#define cpu_ldub_kernel(env, addr) ldub_raw(addr)
-#define cpu_lduw_kernel(env, addr) lduw_raw(addr)
-#define cpu_ldsw_kernel(env, addr) ldsw_raw(addr)
-#define cpu_ldl_kernel(env, addr) ldl_raw(addr)
-#define cpu_ldq_kernel(env, addr) ldq_raw(addr)
-
-#define cpu_stb_kernel(env, addr, data) stb_raw(addr, data)
-#define cpu_stw_kernel(env, addr, data) stw_raw(addr, data)
-#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
-#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
-
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldq_kernel(p) ldq_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
-
-#define cpu_ldub_data(env, addr) ldub_raw(addr)
-#define cpu_lduw_data(env, addr) lduw_raw(addr)
-#define cpu_ldl_data(env, addr) ldl_raw(addr)
-
-#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
-#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
-#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
+#define DATA_SIZE 2
+#include "exec/cpu_ldst_useronly_template.h"
-#else
+#define DATA_SIZE 4
+#include "exec/cpu_ldst_useronly_template.h"
-/* XXX: find something cleaner.
- * Furthermore, this is false for 64 bits targets
- */
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
-#define ldul_hypv ldl_hypv
-#define ldul_executive ldl_executive
-#define ldul_supervisor ldl_supervisor
+#define DATA_SIZE 8
+#include "exec/cpu_ldst_useronly_template.h"
+#undef MEMSUFFIX
+
+#define MEMSUFFIX _code
+#define CODE_ACCESS
+#define DATA_SIZE 1
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 2
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 4
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 8
+#include "exec/cpu_ldst_useronly_template.h"
+#undef MEMSUFFIX
+#undef CODE_ACCESS
+
+#else
/* The memory helpers for tcg-generated code need tcg_target_long etc. */
#include "tcg.h"
@@ -182,6 +132,7 @@ uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+#ifdef MMU_MODE0_SUFFIX
#define CPU_MMU_INDEX 0
#define MEMSUFFIX MMU_MODE0_SUFFIX
#define DATA_SIZE 1
@@ -197,7 +148,9 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#include "exec/cpu_ldst_template.h"
#undef CPU_MMU_INDEX
#undef MEMSUFFIX
+#endif
+#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
#define CPU_MMU_INDEX 1
#define MEMSUFFIX MMU_MODE1_SUFFIX
#define DATA_SIZE 1
@@ -213,8 +166,9 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#include "exec/cpu_ldst_template.h"
#undef CPU_MMU_INDEX
#undef MEMSUFFIX
+#endif
-#if (NB_MMU_MODES >= 3)
+#if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
#define CPU_MMU_INDEX 2
#define MEMSUFFIX MMU_MODE2_SUFFIX
@@ -233,7 +187,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#undef MEMSUFFIX
#endif /* (NB_MMU_MODES >= 3) */
-#if (NB_MMU_MODES >= 4)
+#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
#define CPU_MMU_INDEX 3
#define MEMSUFFIX MMU_MODE3_SUFFIX
@@ -252,7 +206,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#undef MEMSUFFIX
#endif /* (NB_MMU_MODES >= 4) */
-#if (NB_MMU_MODES >= 5)
+#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
#define CPU_MMU_INDEX 4
#define MEMSUFFIX MMU_MODE4_SUFFIX
@@ -271,7 +225,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#undef MEMSUFFIX
#endif /* (NB_MMU_MODES >= 5) */
-#if (NB_MMU_MODES >= 6)
+#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
#define CPU_MMU_INDEX 5
#define MEMSUFFIX MMU_MODE5_SUFFIX
@@ -311,18 +265,6 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#undef CPU_MMU_INDEX
#undef MEMSUFFIX
-#define ldub(p) ldub_data(p)
-#define ldsb(p) ldsb_data(p)
-#define lduw(p) lduw_data(p)
-#define ldsw(p) ldsw_data(p)
-#define ldl(p) ldl_data(p)
-#define ldq(p) ldq_data(p)
-
-#define stb(p, v) stb_data(p, v)
-#define stw(p, v) stw_data(p, v)
-#define stl(p, v) stl_data(p, v)
-#define stq(p, v) stq_data(p, v)
-
#define CPU_MMU_INDEX (cpu_mmu_index(env))
#define MEMSUFFIX _code
#define SOFTMMU_CODE_ACCESS
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index 006093ac49..95ab7504e2 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -4,9 +4,7 @@
* Generate inline load/store functions for one MMU mode and data
* size.
*
- * Generate a store function as well as signed and unsigned loads. For
- * 32 and 64 bit cases, also generate floating point functions with
- * the same size.
+ * Generate a store function as well as signed and unsigned loads.
*
* Not used directly but included from cpu_ldst.h.
*
@@ -79,7 +77,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
+ res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
}
return res;
}
@@ -101,7 +99,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
MMUSUFFIX)(env, addr, mmu_idx);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
+ res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
}
return res;
}
@@ -127,60 +125,10 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
} else {
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- glue(glue(st, SUFFIX), _raw)(hostaddr, v);
+ glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
}
}
-
-
-#if DATA_SIZE == 8
-static inline float64 glue(cpu_ldfq, MEMSUFFIX)(CPUArchState *env,
- target_ulong ptr)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.i = glue(cpu_ldq, MEMSUFFIX)(env, ptr);
- return u.d;
-}
-
-static inline void glue(cpu_stfq, MEMSUFFIX)(CPUArchState *env,
- target_ulong ptr, float64 v)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.d = v;
- glue(cpu_stq, MEMSUFFIX)(env, ptr, u.i);
-}
-#endif /* DATA_SIZE == 8 */
-
-#if DATA_SIZE == 4
-static inline float32 glue(cpu_ldfl, MEMSUFFIX)(CPUArchState *env,
- target_ulong ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = glue(cpu_ldl, MEMSUFFIX)(env, ptr);
- return u.f;
-}
-
-static inline void glue(cpu_stfl, MEMSUFFIX)(CPUArchState *env,
- target_ulong ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- glue(cpu_stl, MEMSUFFIX)(env, ptr, u.i);
-}
-#endif /* DATA_SIZE == 4 */
-
#endif /* !SOFTMMU_CODE_ACCESS */
#undef RES_TYPE
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
new file mode 100644
index 0000000000..b3b865fae8
--- /dev/null
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -0,0 +1,81 @@
+/*
+ * User-only accessor function support
+ *
+ * Generate inline load/store functions for one data size.
+ *
+ * Generate a store function as well as signed and unsigned loads.
+ *
+ * Not used directly but included from cpu_ldst.h.
+ *
+ * Copyright (c) 2015 Linaro Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#if DATA_SIZE == 8
+#define SUFFIX q
+#define USUFFIX q
+#define DATA_TYPE uint64_t
+#elif DATA_SIZE == 4
+#define SUFFIX l
+#define USUFFIX l
+#define DATA_TYPE uint32_t
+#elif DATA_SIZE == 2
+#define SUFFIX w
+#define USUFFIX uw
+#define DATA_TYPE uint16_t
+#define DATA_STYPE int16_t
+#elif DATA_SIZE == 1
+#define SUFFIX b
+#define USUFFIX ub
+#define DATA_TYPE uint8_t
+#define DATA_STYPE int8_t
+#else
+#error unsupported data size
+#endif
+
+#if DATA_SIZE == 8
+#define RES_TYPE uint64_t
+#else
+#define RES_TYPE uint32_t
+#endif
+
+static inline RES_TYPE
+glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+{
+ return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
+}
+
+#if DATA_SIZE <= 2
+static inline int
+glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+{
+ return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
+}
+#endif
+
+#ifndef CODE_ACCESS
+static inline void
+glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
+ RES_TYPE v)
+{
+ glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
+}
+#endif
+
+#undef RES_TYPE
+#undef DATA_TYPE
+#undef DATA_STYPE
+#undef SUFFIX
+#undef USUFFIX
+#undef DATA_SIZE
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 78c1ced4e7..07d88de746 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -204,7 +204,7 @@ typedef union {
* f : float access
*
* sign is:
- * (empty): for floats or 32 bit size
+ * (empty): for 32 or 64 bit sizes (including floats and doubles)
* u : unsigned
* s : signed
*
@@ -218,7 +218,16 @@ typedef union {
* he : host endian
* be : big endian
* le : little endian
+ * te : target endian
* (except for byte accesses, which have no endian infix).
+ *
+ * The target endian accessors are obviously only available to source
+ * files which are built per-target; they are defined in cpu-all.h.
+ *
+ * In all cases these functions take a host pointer.
+ * For accessors that take a guest address rather than a
+ * host address, see the cpu_{ld,st}_* accessors defined in
+ * cpu_ldst.h.
*/
static inline int ldub_p(const void *ptr)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e2596a4201..399c021337 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -829,8 +829,11 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info *
_regs->gpr[1] = infop->start_stack;
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
if (get_ppc64_abi(infop) < 2) {
- _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_bias;
- infop->entry = ldq_raw(infop->entry) + infop->load_bias;
+ uint64_t val;
+ get_user_u64(val, infop->entry + 8);
+ _regs->gpr[2] = val + infop->load_bias;
+ get_user_u64(val, infop->entry);
+ infop->entry = val + infop->load_bias;
} else {
_regs->gpr[12] = infop->entry; /* r12 set to global entry address */
}
diff --git a/linux-user/main.c b/linux-user/main.c
index 67b02316c1..8c70be4c1b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2972,7 +2972,7 @@ void cpu_loop(CPUM68KState *env)
{
if (ts->sim_syscalls) {
uint16_t nr;
- nr = lduw(env->pc + 2);
+ get_user_u16(nr, env->pc + 2);
env->pc += 4;
do_m68k_simcall(env, nr);
} else {
@@ -3436,10 +3436,8 @@ CPUArchState *cpu_copy(CPUArchState *env)
CPUState *cpu = ENV_GET_CPU(env);
CPUArchState *new_env = cpu_init(cpu_model);
CPUState *new_cpu = ENV_GET_CPU(new_env);
-#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
CPUWatchpoint *wp;
-#endif
/* Reset non arch specific state */
cpu_reset(new_cpu);
@@ -3451,14 +3449,12 @@ CPUArchState *cpu_copy(CPUArchState *env)
BP_CPU break/watchpoints are handled correctly on clone. */
QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
-#if defined(TARGET_HAS_ICE)
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
}
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
}
-#endif
return new_env;
}
diff --git a/linux-user/vm86.c b/linux-user/vm86.c
index 45ef559ec6..22a4eb9625 100644
--- a/linux-user/vm86.c
+++ b/linux-user/vm86.c
@@ -45,29 +45,34 @@ static inline int is_revectored(int nr, struct target_revectored_struct *bitmap)
return (((uint8_t *)bitmap)[nr >> 3] >> (nr & 7)) & 1;
}
-static inline void vm_putw(uint32_t segptr, unsigned int reg16, unsigned int val)
+static inline void vm_putw(CPUX86State *env, uint32_t segptr,
+ unsigned int reg16, unsigned int val)
{
- stw(segptr + (reg16 & 0xffff), val);
+ cpu_stw_data(env, segptr + (reg16 & 0xffff), val);
}
-static inline void vm_putl(uint32_t segptr, unsigned int reg16, unsigned int val)
+static inline void vm_putl(CPUX86State *env, uint32_t segptr,
+ unsigned int reg16, unsigned int val)
{
- stl(segptr + (reg16 & 0xffff), val);
+ cpu_stl_data(env, segptr + (reg16 & 0xffff), val);
}
-static inline unsigned int vm_getb(uint32_t segptr, unsigned int reg16)
+static inline unsigned int vm_getb(CPUX86State *env,
+ uint32_t segptr, unsigned int reg16)
{
- return ldub(segptr + (reg16 & 0xffff));
+ return cpu_ldub_data(env, segptr + (reg16 & 0xffff));
}
-static inline unsigned int vm_getw(uint32_t segptr, unsigned int reg16)
+static inline unsigned int vm_getw(CPUX86State *env,
+ uint32_t segptr, unsigned int reg16)
{
- return lduw(segptr + (reg16 & 0xffff));
+ return cpu_lduw_data(env, segptr + (reg16 & 0xffff));
}
-static inline unsigned int vm_getl(uint32_t segptr, unsigned int reg16)
+static inline unsigned int vm_getl(CPUX86State *env,
+ uint32_t segptr, unsigned int reg16)
{
- return ldl(segptr + (reg16 & 0xffff));
+ return cpu_ldl_data(env, segptr + (reg16 & 0xffff));
}
void save_v86_state(CPUX86State *env)
@@ -221,7 +226,7 @@ static void do_int(CPUX86State *env, int intno)
&ts->vm86plus.int21_revectored))
goto cannot_handle;
int_addr = (intno << 2);
- segoffs = ldl(int_addr);
+ segoffs = cpu_ldl_data(env, int_addr);
if ((segoffs >> 16) == TARGET_BIOSSEG)
goto cannot_handle;
LOG_VM86("VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",
@@ -229,9 +234,9 @@ static void do_int(CPUX86State *env, int intno)
/* save old state */
ssp = env->segs[R_SS].selector << 4;
sp = env->regs[R_ESP] & 0xffff;
- vm_putw(ssp, sp - 2, get_vflags(env));
- vm_putw(ssp, sp - 4, env->segs[R_CS].selector);
- vm_putw(ssp, sp - 6, env->eip);
+ vm_putw(env, ssp, sp - 2, get_vflags(env));
+ vm_putw(env, ssp, sp - 4, env->segs[R_CS].selector);
+ vm_putw(env, ssp, sp - 6, env->eip);
ADD16(env->regs[R_ESP], -6);
/* goto interrupt handler */
env->eip = segoffs & 0xffff;
@@ -285,7 +290,7 @@ void handle_vm86_fault(CPUX86State *env)
data32 = 0;
pref_done = 0;
do {
- opcode = vm_getb(csp, ip);
+ opcode = vm_getb(env, csp, ip);
ADD16(ip, 1);
switch (opcode) {
case 0x66: /* 32-bit data */ data32=1; break;
@@ -306,10 +311,10 @@ void handle_vm86_fault(CPUX86State *env)
switch(opcode) {
case 0x9c: /* pushf */
if (data32) {
- vm_putl(ssp, sp - 4, get_vflags(env));
+ vm_putl(env, ssp, sp - 4, get_vflags(env));
ADD16(env->regs[R_ESP], -4);
} else {
- vm_putw(ssp, sp - 2, get_vflags(env));
+ vm_putw(env, ssp, sp - 2, get_vflags(env));
ADD16(env->regs[R_ESP], -2);
}
env->eip = ip;
@@ -317,10 +322,10 @@ void handle_vm86_fault(CPUX86State *env)
case 0x9d: /* popf */
if (data32) {
- newflags = vm_getl(ssp, sp);
+ newflags = vm_getl(env, ssp, sp);
ADD16(env->regs[R_ESP], 4);
} else {
- newflags = vm_getw(ssp, sp);
+ newflags = vm_getw(env, ssp, sp);
ADD16(env->regs[R_ESP], 2);
}
env->eip = ip;
@@ -335,7 +340,7 @@ void handle_vm86_fault(CPUX86State *env)
VM86_FAULT_RETURN;
case 0xcd: /* int */
- intno = vm_getb(csp, ip);
+ intno = vm_getb(env, csp, ip);
ADD16(ip, 1);
env->eip = ip;
if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {
@@ -350,14 +355,14 @@ void handle_vm86_fault(CPUX86State *env)
case 0xcf: /* iret */
if (data32) {
- newip = vm_getl(ssp, sp) & 0xffff;
- newcs = vm_getl(ssp, sp + 4) & 0xffff;
- newflags = vm_getl(ssp, sp + 8);
+ newip = vm_getl(env, ssp, sp) & 0xffff;
+ newcs = vm_getl(env, ssp, sp + 4) & 0xffff;
+ newflags = vm_getl(env, ssp, sp + 8);
ADD16(env->regs[R_ESP], 12);
} else {
- newip = vm_getw(ssp, sp);
- newcs = vm_getw(ssp, sp + 2);
- newflags = vm_getw(ssp, sp + 4);
+ newip = vm_getw(env, ssp, sp);
+ newcs = vm_getw(env, ssp, sp + 2);
+ newflags = vm_getw(env, ssp, sp + 4);
ADD16(env->regs[R_ESP], 6);
}
env->eip = newip;
diff --git a/monitor.c b/monitor.c
index 1808e41932..7e4f605e6d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1292,16 +1292,16 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
switch(wsize) {
default:
case 1:
- v = ldub_raw(buf + i);
+ v = ldub_p(buf + i);
break;
case 2:
- v = lduw_raw(buf + i);
+ v = lduw_p(buf + i);
break;
case 4:
- v = (uint32_t)ldl_raw(buf + i);
+ v = (uint32_t)ldl_p(buf + i);
break;
case 8:
- v = ldq_raw(buf + i);
+ v = ldq_p(buf + i);
break;
}
monitor_printf(mon, " ");
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index d2f815bca2..1eb272dd26 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -99,6 +99,14 @@ struct %(name)s
ret += generate_struct_fields(members)
+ # Make sure that all structs have at least one field; this avoids
+ # potential issues with attempting to malloc space for zero-length structs
+ # in C, and also incompatibility with C++ (where an empty struct is size 1).
+ if not base and not members:
+ ret += mcgen('''
+ char qapi_dummy_field_for_empty_struct;
+''')
+
if len(fieldname):
fieldname = " " + fieldname
ret += mcgen('''
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index d9b861f404..e276dbf9a2 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -32,8 +32,6 @@
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE EM_ALPHA
#define ICACHE_LINE_SIZE 32
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7ba55f0c2e..cd7a9e8e14 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -39,8 +39,6 @@
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index b88c147518..eea14b6462 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -29,8 +29,6 @@
#include "exec/cpu-defs.h"
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE EM_CRIS
#define EXCP_NMI 1
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3ecff96325..da3358787c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -37,8 +37,6 @@
close to the modifying instruction */
#define TARGET_HAS_PRECISE_SMC
-#define TARGET_HAS_ICE 1
-
#ifdef TARGET_X86_64
#define ELF_MACHINE EM_X86_64
#define ELF_MACHINE_UNAME "x86_64"
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index c98eeb4351..fa374d0c0b 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -34,7 +34,21 @@
# define LOG_PCALL_STATE(cpu) do { } while (0)
#endif
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+#define MEMSUFFIX _kernel
+#define DATA_SIZE 1
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 2
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 4
+#include "exec/cpu_ldst_useronly_template.h"
+
+#define DATA_SIZE 8
+#include "exec/cpu_ldst_useronly_template.h"
+#undef MEMSUFFIX
+#else
#define CPU_MMU_INDEX (cpu_mmu_index_kernel(env))
#define MEMSUFFIX _kernel
#define DATA_SIZE 1
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 0dab6e89ab..e558c59499 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -30,8 +30,6 @@
struct CPULM32State;
typedef struct CPULM32State CPULM32State;
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE EM_LATTICEMICO32
#define NB_MMU_MODES 1
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index f67bbcc646..3a1b9ab938 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -32,8 +32,6 @@
#define MAX_QREGS 32
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE EM_68K
#define EXCP_ACCESS 2 /* Access (MMU) error. */
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 6ccd06068c..5794f8991a 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -34,8 +34,6 @@ typedef struct CPUMBState CPUMBState;
#include "mmu.h"
#endif
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE EM_MICROBLAZE
#define EXCP_NMI 1
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 8875c975e0..5ea61bceea 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -4,7 +4,6 @@
//#define DEBUG_OP
#define ALIGNED_ONLY
-#define TARGET_HAS_ICE 1
#define ELF_MACHINE EM_MIPS
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index d619ba4785..ea7d95f36c 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -74,7 +74,7 @@ void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
static inline type do_##name(CPUMIPSState *env, target_ulong addr, \
int mem_idx) \
{ \
- return (type) insn##_raw(addr); \
+ return (type) cpu_##insn##_data(env, addr); \
}
#else
#define HELPER_LD(name, insn, type) \
@@ -101,7 +101,7 @@ HELPER_LD(ld, ldq, int64_t)
static inline void do_##name(CPUMIPSState *env, target_ulong addr, \
type val, int mem_idx) \
{ \
- insn##_raw(addr, val); \
+ cpu_##insn##_data(env, addr, val); \
}
#else
#define HELPER_ST(name, insn, type) \
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index c5b12a5244..d809393670 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -26,8 +26,6 @@
#define CPUArchState struct CPUMoxieState
-#define TARGET_HAS_ICE 1
-
#define ELF_MACHINE 0xFEED /* EM_MOXIE */
#define MOXIE_EX_DIV0 0
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index c62097bb8a..aae33a9237 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -79,8 +79,6 @@
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
#if defined (TARGET_PPC64)
#define ELF_MACHINE EM_PPC64
#else
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 23ad336803..c123b6f023 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -886,8 +886,6 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
uint64_t vr);
-#define TARGET_HAS_ICE 1
-
/* The value of the TOD clock for 1.1.1970. */
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index a2e9e2c031..b2fb1990dd 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -23,7 +23,6 @@
#include "qemu-common.h"
#define TARGET_LONG_BITS 32
-#define TARGET_HAS_ICE 1
#define ELF_MACHINE EM_SH
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 836f87f42f..0a50e5d113 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -31,8 +31,6 @@
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
#if !defined(TARGET_SPARC64)
#define ELF_MACHINE EM_SPARC
#else
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 1a62e193bd..e62228c998 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1122,17 +1122,17 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
{
switch (size) {
case 1:
- ret = ldub_raw(addr);
+ ret = cpu_ldub_data(env, addr);
break;
case 2:
- ret = lduw_raw(addr);
+ ret = cpu_lduw_data(env, addr);
break;
case 4:
- ret = ldl_raw(addr);
+ ret = cpu_ldl_data(env, addr);
break;
default:
case 8:
- ret = ldq_raw(addr);
+ ret = cpu_ldq_data(env, addr);
break;
}
}
@@ -1239,17 +1239,17 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
{
switch (size) {
case 1:
- stb_raw(addr, val);
+ cpu_stb_data(env, addr, val);
break;
case 2:
- stw_raw(addr, val);
+ cpu_stw_data(env, addr, val);
break;
case 4:
- stl_raw(addr, val);
+ cpu_stl_data(env, addr, val);
break;
case 8:
default:
- stq_raw(addr, val);
+ cpu_stq_data(env, addr, val);
break;
}
}
@@ -2289,8 +2289,8 @@ void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
break;
}
#else
- u.ll.upper = ldq_raw(address_mask(env, addr));
- u.ll.lower = ldq_raw(address_mask(env, addr + 8));
+ u.ll.upper = cpu_ldq_data(env, address_mask(env, addr));
+ u.ll.lower = cpu_ldq_data(env, address_mask(env, addr + 8));
QT0 = u.q;
#endif
}
@@ -2326,8 +2326,8 @@ void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
}
#else
u.q = QT0;
- stq_raw(address_mask(env, addr), u.ll.upper);
- stq_raw(address_mask(env, addr + 8), u.ll.lower);
+ cpu_stq_data(env, address_mask(env, addr), u.ll.upper);
+ cpu_stq_data(env, address_mask(env, addr + 8), u.ll.lower);
#endif
}
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index a1bfbf7acf..60ee563080 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -39,8 +39,6 @@
#include "exec/cpu-defs.h"
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
#define NB_MMU_MODES 4
#define TARGET_PHYS_ADDR_SPACE_BITS 32
diff --git a/translate-all.c b/translate-all.c
index 687ba7d177..4a1b64fd83 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1451,7 +1451,7 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
return &tcg_ctx.tb_ctx.tbs[m_max];
}
-#if defined(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
{
ram_addr_t ram_addr;
@@ -1467,7 +1467,7 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
+ addr;
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
}
-#endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
+#endif /* !defined(CONFIG_USER_ONLY) */
void tb_check_watchpoint(CPUState *cpu)
{