target/arm: Prepare generic timer for per-platform CNTFRQ
[qemu/ar7.git] / include / exec / cpu_ldst_template.h
blob54b5e858cee090146b89b58c940c86ad11ade9a6
1 /*
2 * Software MMU support
4 * Generate inline load/store functions for one MMU mode and data
5 * size.
7 * Generate a store function as well as signed and unsigned loads.
9 * Not used directly but included from cpu_ldst.h.
11 * Copyright (c) 2003 Fabrice Bellard
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 #if !defined(SOFTMMU_CODE_ACCESS)
28 #include "trace-root.h"
29 #endif
31 #include "qemu/plugin.h"
32 #include "trace/mem.h"
34 #if DATA_SIZE == 8
35 #define SUFFIX q
36 #define USUFFIX q
37 #define DATA_TYPE uint64_t
38 #define SHIFT 3
39 #elif DATA_SIZE == 4
40 #define SUFFIX l
41 #define USUFFIX l
42 #define DATA_TYPE uint32_t
43 #define SHIFT 2
44 #elif DATA_SIZE == 2
45 #define SUFFIX w
46 #define USUFFIX uw
47 #define DATA_TYPE uint16_t
48 #define DATA_STYPE int16_t
49 #define SHIFT 1
50 #elif DATA_SIZE == 1
51 #define SUFFIX b
52 #define USUFFIX ub
53 #define DATA_TYPE uint8_t
54 #define DATA_STYPE int8_t
55 #define SHIFT 0
56 #else
57 #error unsupported data size
58 #endif
60 #if DATA_SIZE == 8
61 #define RES_TYPE uint64_t
62 #else
63 #define RES_TYPE uint32_t
64 #endif
66 #ifdef SOFTMMU_CODE_ACCESS
67 #define ADDR_READ addr_code
68 #define MMUSUFFIX _cmmu
69 #define URETSUFFIX USUFFIX
70 #define SRETSUFFIX glue(s, SUFFIX)
71 #else
72 #define ADDR_READ addr_read
73 #define MMUSUFFIX _mmu
74 #define URETSUFFIX USUFFIX
75 #define SRETSUFFIX glue(s, SUFFIX)
76 #endif
78 /* generic load/store macros */
80 static inline RES_TYPE
81 glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
82 target_ulong ptr,
83 uintptr_t retaddr)
85 CPUTLBEntry *entry;
86 RES_TYPE res;
87 target_ulong addr;
88 int mmu_idx = CPU_MMU_INDEX;
89 TCGMemOpIdx oi;
90 #if !defined(SOFTMMU_CODE_ACCESS)
91 uint16_t meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false, mmu_idx);
92 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
93 #endif
95 addr = ptr;
96 entry = tlb_entry(env, mmu_idx, addr);
97 if (unlikely(entry->ADDR_READ !=
98 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
99 oi = make_memop_idx(SHIFT, mmu_idx);
100 res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
101 oi, retaddr);
102 } else {
103 uintptr_t hostaddr = addr + entry->addend;
104 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
106 #ifndef SOFTMMU_CODE_ACCESS
107 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
108 #endif
109 return res;
112 static inline RES_TYPE
113 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
115 return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
118 #if DATA_SIZE <= 2
119 static inline int
120 glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
121 target_ulong ptr,
122 uintptr_t retaddr)
124 CPUTLBEntry *entry;
125 int res;
126 target_ulong addr;
127 int mmu_idx = CPU_MMU_INDEX;
128 TCGMemOpIdx oi;
129 #if !defined(SOFTMMU_CODE_ACCESS)
130 uint16_t meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false, mmu_idx);
131 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
132 #endif
134 addr = ptr;
135 entry = tlb_entry(env, mmu_idx, addr);
136 if (unlikely(entry->ADDR_READ !=
137 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
138 oi = make_memop_idx(SHIFT, mmu_idx);
139 res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
140 MMUSUFFIX)(env, addr, oi, retaddr);
141 } else {
142 uintptr_t hostaddr = addr + entry->addend;
143 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
145 #ifndef SOFTMMU_CODE_ACCESS
146 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
147 #endif
148 return res;
151 static inline int
152 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
154 return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
156 #endif
158 #ifndef SOFTMMU_CODE_ACCESS
160 /* generic store macro */
162 static inline void
163 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
164 target_ulong ptr,
165 RES_TYPE v, uintptr_t retaddr)
167 CPUTLBEntry *entry;
168 target_ulong addr;
169 int mmu_idx = CPU_MMU_INDEX;
170 TCGMemOpIdx oi;
171 #if !defined(SOFTMMU_CODE_ACCESS)
172 uint16_t meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true, mmu_idx);
173 trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
174 #endif
176 addr = ptr;
177 entry = tlb_entry(env, mmu_idx, addr);
178 if (unlikely(tlb_addr_write(entry) !=
179 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
180 oi = make_memop_idx(SHIFT, mmu_idx);
181 glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
182 retaddr);
183 } else {
184 uintptr_t hostaddr = addr + entry->addend;
185 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
187 #ifndef SOFTMMU_CODE_ACCESS
188 qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
189 #endif
192 static inline void
193 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
194 RES_TYPE v)
196 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
199 #endif /* !SOFTMMU_CODE_ACCESS */
201 #undef RES_TYPE
202 #undef DATA_TYPE
203 #undef DATA_STYPE
204 #undef SUFFIX
205 #undef USUFFIX
206 #undef DATA_SIZE
207 #undef MMUSUFFIX
208 #undef ADDR_READ
209 #undef URETSUFFIX
210 #undef SRETSUFFIX
211 #undef SHIFT