master
h 474 lines 13.8 KB
Raw
1 /*
2 * Software MMU support (per-target)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 /*
20 * Generate inline load/store functions for all MMU modes (typically
21 * at least _user and _kernel) as well as _data versions, for all data
22 * sizes.
23 *
24 * Used by target op helpers.
25 *
26 * The syntax for the accessors is:
27 *
28 * load: cpu_ld{sign}{size}{end}_{mmusuffix}(env, ptr)
29 * cpu_ld{sign}{size}{end}_{mmusuffix}_ra(env, ptr, retaddr)
30 * cpu_ld{sign}{size}{end}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
31 * cpu_ld{sign}{size}{end}_mmu(env, ptr, oi, retaddr)
32 *
33 * store: cpu_st{size}{end}_{mmusuffix}(env, ptr, val)
34 * cpu_st{size}{end}_{mmusuffix}_ra(env, ptr, val, retaddr)
35 * cpu_st{size}{end}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
36 * cpu_st{size}{end}_mmu(env, ptr, val, oi, retaddr)
37 *
38 * sign is:
39 * (empty): for 32 and 64 bit sizes
40 * u : unsigned
41 * s : signed
42 *
43 * size is:
44 * b: 8 bits
45 * w: 16 bits
46 * l: 32 bits
47 * q: 64 bits
48 *
49 * end is:
50 * (empty): for target native endian, or for 8 bit access
51 * _be: for forced big endian
52 * _le: for forced little endian
53 *
54 * mmusuffix is one of the generic suffixes "data" or "mmuidx".
55 * The "mmuidx" suffix carries an extra mmu_idx argument that specifies
56 * the index to use; the "data" suffix take the index from cpu_mmu_index().
57 *
58 * The "mmu" suffix carries the full MemOpIdx, with both mmu_idx and the
59 * MemOp including alignment requirements. The alignment will be enforced.
60 */
61 #ifndef ACCEL_TCG_CPU_LDST_H
62 #define ACCEL_TCG_CPU_LDST_H
63
64 #ifndef CONFIG_TCG
65 #error Can only include this header with TCG
66 #endif
67
68 #include "exec/cpu-common.h"
69 #include "accel/tcg/cpu-ldst-common.h"
70 #include "accel/tcg/cpu-mmu-index.h"
71 #include "exec/abi_ptr.h"
72
73 static inline uint32_t
74 cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr, int mmu_idx, uintptr_t ra)
75 {
76 MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
77 return cpu_ldb_mmu(env, addr, oi, ra);
78 }
79
80 static inline int
81 cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr, int mmu_idx, uintptr_t ra)
82 {
83 return (int8_t)cpu_ldub_mmuidx_ra(env, addr, mmu_idx, ra);
84 }
85
86 static inline uint32_t
87 cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
88 int mmu_idx, uintptr_t ra)
89 {
90 MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
91 return cpu_ldw_mmu(env, addr, oi, ra);
92 }
93
94 static inline int
95 cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
96 int mmu_idx, uintptr_t ra)
97 {
98 return (int16_t)cpu_lduw_be_mmuidx_ra(env, addr, mmu_idx, ra);
99 }
100
101 static inline uint32_t
102 cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
103 int mmu_idx, uintptr_t ra)
104 {
105 MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
106 return cpu_ldl_mmu(env, addr, oi, ra);
107 }
108
109 static inline uint64_t
110 cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
111 int mmu_idx, uintptr_t ra)
112 {
113 MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
114 return cpu_ldq_mmu(env, addr, oi, ra);
115 }
116
117 static inline uint32_t
118 cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
119 int mmu_idx, uintptr_t ra)
120 {
121 MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
122 return cpu_ldw_mmu(env, addr, oi, ra);
123 }
124
125 static inline int
126 cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
127 int mmu_idx, uintptr_t ra)
128 {
129 return (int16_t)cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, ra);
130 }
131
132 static inline uint32_t
133 cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
134 int mmu_idx, uintptr_t ra)
135 {
136 MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
137 return cpu_ldl_mmu(env, addr, oi, ra);
138 }
139
140 static inline uint64_t
141 cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
142 int mmu_idx, uintptr_t ra)
143 {
144 MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
145 return cpu_ldq_mmu(env, addr, oi, ra);
146 }
147
148 static inline void
149 cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
150 int mmu_idx, uintptr_t ra)
151 {
152 MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
153 cpu_stb_mmu(env, addr, val, oi, ra);
154 }
155
156 static inline void
157 cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
158 int mmu_idx, uintptr_t ra)
159 {
160 MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
161 cpu_stw_mmu(env, addr, val, oi, ra);
162 }
163
164 static inline void
165 cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
166 int mmu_idx, uintptr_t ra)
167 {
168 MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
169 cpu_stl_mmu(env, addr, val, oi, ra);
170 }
171
172 static inline void
173 cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
174 int mmu_idx, uintptr_t ra)
175 {
176 MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
177 cpu_stq_mmu(env, addr, val, oi, ra);
178 }
179
180 static inline void
181 cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
182 int mmu_idx, uintptr_t ra)
183 {
184 MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
185 cpu_stw_mmu(env, addr, val, oi, ra);
186 }
187
188 static inline void
189 cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
190 int mmu_idx, uintptr_t ra)
191 {
192 MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
193 cpu_stl_mmu(env, addr, val, oi, ra);
194 }
195
196 static inline void
197 cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
198 int mmu_idx, uintptr_t ra)
199 {
200 MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
201 cpu_stq_mmu(env, addr, val, oi, ra);
202 }
203
204 /*--------------------------*/
205
206 static inline uint32_t
207 cpu_ldub_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
208 {
209 int mmu_index = cpu_mmu_index(env_cpu(env), false);
210 return cpu_ldub_mmuidx_ra(env, addr, mmu_index, ra);
211 }
212
213 static inline int
214 cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
215 {
216 return (int8_t)cpu_ldub_data_ra(env, addr, ra);
217 }
218
219 static inline uint32_t
220 cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
221 {
222 int mmu_index = cpu_mmu_index(env_cpu(env), false);
223 return cpu_lduw_be_mmuidx_ra(env, addr, mmu_index, ra);
224 }
225
226 static inline int
227 cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
228 {
229 return (int16_t)cpu_lduw_be_data_ra(env, addr, ra);
230 }
231
232 static inline uint32_t
233 cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
234 {
235 int mmu_index = cpu_mmu_index(env_cpu(env), false);
236 return cpu_ldl_be_mmuidx_ra(env, addr, mmu_index, ra);
237 }
238
239 static inline uint64_t
240 cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
241 {
242 int mmu_index = cpu_mmu_index(env_cpu(env), false);
243 return cpu_ldq_be_mmuidx_ra(env, addr, mmu_index, ra);
244 }
245
246 static inline uint32_t
247 cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
248 {
249 int mmu_index = cpu_mmu_index(env_cpu(env), false);
250 return cpu_lduw_le_mmuidx_ra(env, addr, mmu_index, ra);
251 }
252
253 static inline int
254 cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
255 {
256 return (int16_t)cpu_lduw_le_data_ra(env, addr, ra);
257 }
258
259 static inline uint32_t
260 cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
261 {
262 int mmu_index = cpu_mmu_index(env_cpu(env), false);
263 return cpu_ldl_le_mmuidx_ra(env, addr, mmu_index, ra);
264 }
265
266 static inline uint64_t
267 cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
268 {
269 int mmu_index = cpu_mmu_index(env_cpu(env), false);
270 return cpu_ldq_le_mmuidx_ra(env, addr, mmu_index, ra);
271 }
272
273 static inline void
274 cpu_stb_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
275 {
276 int mmu_index = cpu_mmu_index(env_cpu(env), false);
277 cpu_stb_mmuidx_ra(env, addr, val, mmu_index, ra);
278 }
279
280 static inline void
281 cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
282 {
283 int mmu_index = cpu_mmu_index(env_cpu(env), false);
284 cpu_stw_be_mmuidx_ra(env, addr, val, mmu_index, ra);
285 }
286
287 static inline void
288 cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
289 {
290 int mmu_index = cpu_mmu_index(env_cpu(env), false);
291 cpu_stl_be_mmuidx_ra(env, addr, val, mmu_index, ra);
292 }
293
294 static inline void
295 cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr, uint64_t val, uintptr_t ra)
296 {
297 int mmu_index = cpu_mmu_index(env_cpu(env), false);
298 cpu_stq_be_mmuidx_ra(env, addr, val, mmu_index, ra);
299 }
300
301 static inline void
302 cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
303 {
304 int mmu_index = cpu_mmu_index(env_cpu(env), false);
305 cpu_stw_le_mmuidx_ra(env, addr, val, mmu_index, ra);
306 }
307
308 static inline void
309 cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
310 {
311 int mmu_index = cpu_mmu_index(env_cpu(env), false);
312 cpu_stl_le_mmuidx_ra(env, addr, val, mmu_index, ra);
313 }
314
315 static inline void
316 cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr, uint64_t val, uintptr_t ra)
317 {
318 int mmu_index = cpu_mmu_index(env_cpu(env), false);
319 cpu_stq_le_mmuidx_ra(env, addr, val, mmu_index, ra);
320 }
321
322 /*--------------------------*/
323
324 static inline uint32_t
325 cpu_ldub_data(CPUArchState *env, abi_ptr addr)
326 {
327 return cpu_ldub_data_ra(env, addr, 0);
328 }
329
330 static inline int
331 cpu_ldsb_data(CPUArchState *env, abi_ptr addr)
332 {
333 return (int8_t)cpu_ldub_data(env, addr);
334 }
335
336 static inline uint32_t
337 cpu_lduw_be_data(CPUArchState *env, abi_ptr addr)
338 {
339 return cpu_lduw_be_data_ra(env, addr, 0);
340 }
341
342 static inline int
343 cpu_ldsw_be_data(CPUArchState *env, abi_ptr addr)
344 {
345 return (int16_t)cpu_lduw_be_data(env, addr);
346 }
347
348 static inline uint32_t
349 cpu_ldl_be_data(CPUArchState *env, abi_ptr addr)
350 {
351 return cpu_ldl_be_data_ra(env, addr, 0);
352 }
353
354 static inline uint64_t
355 cpu_ldq_be_data(CPUArchState *env, abi_ptr addr)
356 {
357 return cpu_ldq_be_data_ra(env, addr, 0);
358 }
359
360 static inline uint32_t
361 cpu_lduw_le_data(CPUArchState *env, abi_ptr addr)
362 {
363 return cpu_lduw_le_data_ra(env, addr, 0);
364 }
365
366 static inline int
367 cpu_ldsw_le_data(CPUArchState *env, abi_ptr addr)
368 {
369 return (int16_t)cpu_lduw_le_data(env, addr);
370 }
371
372 static inline uint32_t
373 cpu_ldl_le_data(CPUArchState *env, abi_ptr addr)
374 {
375 return cpu_ldl_le_data_ra(env, addr, 0);
376 }
377
378 static inline uint64_t
379 cpu_ldq_le_data(CPUArchState *env, abi_ptr addr)
380 {
381 return cpu_ldq_le_data_ra(env, addr, 0);
382 }
383
384 static inline void
385 cpu_stb_data(CPUArchState *env, abi_ptr addr, uint32_t val)
386 {
387 cpu_stb_data_ra(env, addr, val, 0);
388 }
389
390 static inline void
391 cpu_stw_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
392 {
393 cpu_stw_be_data_ra(env, addr, val, 0);
394 }
395
396 static inline void
397 cpu_stl_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
398 {
399 cpu_stl_be_data_ra(env, addr, val, 0);
400 }
401
402 static inline void
403 cpu_stq_be_data(CPUArchState *env, abi_ptr addr, uint64_t val)
404 {
405 cpu_stq_be_data_ra(env, addr, val, 0);
406 }
407
408 static inline void
409 cpu_stw_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
410 {
411 cpu_stw_le_data_ra(env, addr, val, 0);
412 }
413
414 static inline void
415 cpu_stl_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
416 {
417 cpu_stl_le_data_ra(env, addr, val, 0);
418 }
419
420 static inline void
421 cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
422 {
423 cpu_stq_le_data_ra(env, addr, val, 0);
424 }
425
426 #ifndef TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API
427 #if TARGET_BIG_ENDIAN
428 # define cpu_lduw_data cpu_lduw_be_data
429 # define cpu_ldsw_data cpu_ldsw_be_data
430 # define cpu_ldl_data cpu_ldl_be_data
431 # define cpu_ldq_data cpu_ldq_be_data
432 # define cpu_lduw_data_ra cpu_lduw_be_data_ra
433 # define cpu_ldsw_data_ra cpu_ldsw_be_data_ra
434 # define cpu_ldl_data_ra cpu_ldl_be_data_ra
435 # define cpu_ldq_data_ra cpu_ldq_be_data_ra
436 # define cpu_lduw_mmuidx_ra cpu_lduw_be_mmuidx_ra
437 # define cpu_ldsw_mmuidx_ra cpu_ldsw_be_mmuidx_ra
438 # define cpu_ldl_mmuidx_ra cpu_ldl_be_mmuidx_ra
439 # define cpu_ldq_mmuidx_ra cpu_ldq_be_mmuidx_ra
440 # define cpu_stw_data cpu_stw_be_data
441 # define cpu_stl_data cpu_stl_be_data
442 # define cpu_stq_data cpu_stq_be_data
443 # define cpu_stw_data_ra cpu_stw_be_data_ra
444 # define cpu_stl_data_ra cpu_stl_be_data_ra
445 # define cpu_stq_data_ra cpu_stq_be_data_ra
446 # define cpu_stw_mmuidx_ra cpu_stw_be_mmuidx_ra
447 # define cpu_stl_mmuidx_ra cpu_stl_be_mmuidx_ra
448 # define cpu_stq_mmuidx_ra cpu_stq_be_mmuidx_ra
449 #else
450 # define cpu_lduw_data cpu_lduw_le_data
451 # define cpu_ldsw_data cpu_ldsw_le_data
452 # define cpu_ldl_data cpu_ldl_le_data
453 # define cpu_ldq_data cpu_ldq_le_data
454 # define cpu_lduw_data_ra cpu_lduw_le_data_ra
455 # define cpu_ldsw_data_ra cpu_ldsw_le_data_ra
456 # define cpu_ldl_data_ra cpu_ldl_le_data_ra
457 # define cpu_ldq_data_ra cpu_ldq_le_data_ra
458 # define cpu_lduw_mmuidx_ra cpu_lduw_le_mmuidx_ra
459 # define cpu_ldsw_mmuidx_ra cpu_ldsw_le_mmuidx_ra
460 # define cpu_ldl_mmuidx_ra cpu_ldl_le_mmuidx_ra
461 # define cpu_ldq_mmuidx_ra cpu_ldq_le_mmuidx_ra
462 # define cpu_stw_data cpu_stw_le_data
463 # define cpu_stl_data cpu_stl_le_data
464 # define cpu_stq_data cpu_stq_le_data
465 # define cpu_stw_data_ra cpu_stw_le_data_ra
466 # define cpu_stl_data_ra cpu_stl_le_data_ra
467 # define cpu_stq_data_ra cpu_stq_le_data_ra
468 # define cpu_stw_mmuidx_ra cpu_stw_le_mmuidx_ra
469 # define cpu_stl_mmuidx_ra cpu_stl_le_mmuidx_ra
470 # define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
471 #endif
472 #endif /* TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API */
473
474 #endif /* ACCEL_TCG_CPU_LDST_H */