diff options
Diffstat (limited to 'include/exec')
-rw-r--r-- | include/exec/cpu-all.h | 38 | ||||
-rw-r--r-- | include/exec/cpu_ldst.h | 174 | ||||
-rw-r--r-- | include/exec/cpu_ldst_template.h | 60 | ||||
-rw-r--r-- | include/exec/cpu_ldst_useronly_template.h | 81 |
4 files changed, 145 insertions, 208 deletions
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 |