xref: /openbmc/qemu/accel/tcg/ldst_common.c.inc (revision d0b9b28a)
1/*
2 * Routines common to user and system emulation of load/store.
3 *
4 *  Copyright (c) 2003 Fabrice Bellard
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 *
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
10 */
11/*
12 * Load helpers for tcg-ldst.h
13 */
14
15tcg_target_ulong helper_ldub_mmu(CPUArchState *env, uint64_t addr,
16                                 MemOpIdx oi, uintptr_t retaddr)
17{
18    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
19    return do_ld1_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
20}
21
22tcg_target_ulong helper_lduw_mmu(CPUArchState *env, uint64_t addr,
23                                 MemOpIdx oi, uintptr_t retaddr)
24{
25    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
26    return do_ld2_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
27}
28
29tcg_target_ulong helper_ldul_mmu(CPUArchState *env, uint64_t addr,
30                                 MemOpIdx oi, uintptr_t retaddr)
31{
32    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
33    return do_ld4_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
34}
35
36uint64_t helper_ldq_mmu(CPUArchState *env, uint64_t addr,
37                        MemOpIdx oi, uintptr_t retaddr)
38{
39    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
40    return do_ld8_mmu(env_cpu(env), addr, oi, retaddr, MMU_DATA_LOAD);
41}
42
43/*
44 * Provide signed versions of the load routines as well.  We can of course
45 * avoid this for 64-bit data, or for 32-bit data on 32-bit host.
46 */
47
48tcg_target_ulong helper_ldsb_mmu(CPUArchState *env, uint64_t addr,
49                                 MemOpIdx oi, uintptr_t retaddr)
50{
51    return (int8_t)helper_ldub_mmu(env, addr, oi, retaddr);
52}
53
54tcg_target_ulong helper_ldsw_mmu(CPUArchState *env, uint64_t addr,
55                                 MemOpIdx oi, uintptr_t retaddr)
56{
57    return (int16_t)helper_lduw_mmu(env, addr, oi, retaddr);
58}
59
60tcg_target_ulong helper_ldsl_mmu(CPUArchState *env, uint64_t addr,
61                                 MemOpIdx oi, uintptr_t retaddr)
62{
63    return (int32_t)helper_ldul_mmu(env, addr, oi, retaddr);
64}
65
66Int128 helper_ld16_mmu(CPUArchState *env, uint64_t addr,
67                       MemOpIdx oi, uintptr_t retaddr)
68{
69    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
70    return do_ld16_mmu(env_cpu(env), addr, oi, retaddr);
71}
72
73Int128 helper_ld_i128(CPUArchState *env, uint64_t addr, uint32_t oi)
74{
75    return helper_ld16_mmu(env, addr, oi, GETPC());
76}
77
78/*
79 * Store helpers for tcg-ldst.h
80 */
81
82void helper_stb_mmu(CPUArchState *env, uint64_t addr, uint32_t val,
83                    MemOpIdx oi, uintptr_t ra)
84{
85    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_8);
86    do_st1_mmu(env_cpu(env), addr, val, oi, ra);
87}
88
89void helper_stw_mmu(CPUArchState *env, uint64_t addr, uint32_t val,
90                    MemOpIdx oi, uintptr_t retaddr)
91{
92    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
93    do_st2_mmu(env_cpu(env), addr, val, oi, retaddr);
94}
95
96void helper_stl_mmu(CPUArchState *env, uint64_t addr, uint32_t val,
97                    MemOpIdx oi, uintptr_t retaddr)
98{
99    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
100    do_st4_mmu(env_cpu(env), addr, val, oi, retaddr);
101}
102
103void helper_stq_mmu(CPUArchState *env, uint64_t addr, uint64_t val,
104                    MemOpIdx oi, uintptr_t retaddr)
105{
106    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
107    do_st8_mmu(env_cpu(env), addr, val, oi, retaddr);
108}
109
110void helper_st16_mmu(CPUArchState *env, uint64_t addr, Int128 val,
111                     MemOpIdx oi, uintptr_t retaddr)
112{
113    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
114    do_st16_mmu(env_cpu(env), addr, val, oi, retaddr);
115}
116
117void helper_st_i128(CPUArchState *env, uint64_t addr, Int128 val, MemOpIdx oi)
118{
119    helper_st16_mmu(env, addr, val, oi, GETPC());
120}
121
122/*
123 * Load helpers for cpu_ldst.h
124 */
125
126static void plugin_load_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
127{
128    if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
129        qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
130    }
131}
132
133uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra)
134{
135    uint8_t ret;
136
137    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_UB);
138    ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
139    plugin_load_cb(env, addr, oi);
140    return ret;
141}
142
143uint16_t cpu_ldw_mmu(CPUArchState *env, abi_ptr addr,
144                     MemOpIdx oi, uintptr_t ra)
145{
146    uint16_t ret;
147
148    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
149    ret = do_ld2_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
150    plugin_load_cb(env, addr, oi);
151    return ret;
152}
153
154uint32_t cpu_ldl_mmu(CPUArchState *env, abi_ptr addr,
155                     MemOpIdx oi, uintptr_t ra)
156{
157    uint32_t ret;
158
159    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
160    ret = do_ld4_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
161    plugin_load_cb(env, addr, oi);
162    return ret;
163}
164
165uint64_t cpu_ldq_mmu(CPUArchState *env, abi_ptr addr,
166                     MemOpIdx oi, uintptr_t ra)
167{
168    uint64_t ret;
169
170    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
171    ret = do_ld8_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
172    plugin_load_cb(env, addr, oi);
173    return ret;
174}
175
176Int128 cpu_ld16_mmu(CPUArchState *env, abi_ptr addr,
177                    MemOpIdx oi, uintptr_t ra)
178{
179    Int128 ret;
180
181    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
182    ret = do_ld16_mmu(env_cpu(env), addr, oi, ra);
183    plugin_load_cb(env, addr, oi);
184    return ret;
185}
186
187/*
188 * Store helpers for cpu_ldst.h
189 */
190
191static void plugin_store_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
192{
193    if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
194        qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
195    }
196}
197
198void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
199                 MemOpIdx oi, uintptr_t retaddr)
200{
201    helper_stb_mmu(env, addr, val, oi, retaddr);
202    plugin_store_cb(env, addr, oi);
203}
204
205void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
206                 MemOpIdx oi, uintptr_t retaddr)
207{
208    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
209    do_st2_mmu(env_cpu(env), addr, val, oi, retaddr);
210    plugin_store_cb(env, addr, oi);
211}
212
213void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
214                    MemOpIdx oi, uintptr_t retaddr)
215{
216    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
217    do_st4_mmu(env_cpu(env), addr, val, oi, retaddr);
218    plugin_store_cb(env, addr, oi);
219}
220
221void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
222                 MemOpIdx oi, uintptr_t retaddr)
223{
224    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
225    do_st8_mmu(env_cpu(env), addr, val, oi, retaddr);
226    plugin_store_cb(env, addr, oi);
227}
228
229void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
230                  MemOpIdx oi, uintptr_t retaddr)
231{
232    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
233    do_st16_mmu(env_cpu(env), addr, val, oi, retaddr);
234    plugin_store_cb(env, addr, oi);
235}
236
237/*
238 * Wrappers of the above
239 */
240
241uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
242                            int mmu_idx, uintptr_t ra)
243{
244    MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
245    return cpu_ldb_mmu(env, addr, oi, ra);
246}
247
248int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
249                       int mmu_idx, uintptr_t ra)
250{
251    return (int8_t)cpu_ldub_mmuidx_ra(env, addr, mmu_idx, ra);
252}
253
254uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
255                               int mmu_idx, uintptr_t ra)
256{
257    MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
258    return cpu_ldw_mmu(env, addr, oi, ra);
259}
260
261int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
262                          int mmu_idx, uintptr_t ra)
263{
264    return (int16_t)cpu_lduw_be_mmuidx_ra(env, addr, mmu_idx, ra);
265}
266
267uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
268                              int mmu_idx, uintptr_t ra)
269{
270    MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
271    return cpu_ldl_mmu(env, addr, oi, ra);
272}
273
274uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
275                              int mmu_idx, uintptr_t ra)
276{
277    MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
278    return cpu_ldq_mmu(env, addr, oi, ra);
279}
280
281uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
282                               int mmu_idx, uintptr_t ra)
283{
284    MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
285    return cpu_ldw_mmu(env, addr, oi, ra);
286}
287
288int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
289                          int mmu_idx, uintptr_t ra)
290{
291    return (int16_t)cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, ra);
292}
293
294uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
295                              int mmu_idx, uintptr_t ra)
296{
297    MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
298    return cpu_ldl_mmu(env, addr, oi, ra);
299}
300
301uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
302                              int mmu_idx, uintptr_t ra)
303{
304    MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
305    return cpu_ldq_mmu(env, addr, oi, ra);
306}
307
308void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
309                       int mmu_idx, uintptr_t ra)
310{
311    MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
312    cpu_stb_mmu(env, addr, val, oi, ra);
313}
314
315void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
316                          int mmu_idx, uintptr_t ra)
317{
318    MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
319    cpu_stw_mmu(env, addr, val, oi, ra);
320}
321
322void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
323                          int mmu_idx, uintptr_t ra)
324{
325    MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
326    cpu_stl_mmu(env, addr, val, oi, ra);
327}
328
329void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
330                          int mmu_idx, uintptr_t ra)
331{
332    MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
333    cpu_stq_mmu(env, addr, val, oi, ra);
334}
335
336void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
337                          int mmu_idx, uintptr_t ra)
338{
339    MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
340    cpu_stw_mmu(env, addr, val, oi, ra);
341}
342
343void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
344                          int mmu_idx, uintptr_t ra)
345{
346    MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
347    cpu_stl_mmu(env, addr, val, oi, ra);
348}
349
350void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
351                          int mmu_idx, uintptr_t ra)
352{
353    MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
354    cpu_stq_mmu(env, addr, val, oi, ra);
355}
356
357/*--------------------------*/
358
359uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
360{
361    int mmu_index = cpu_mmu_index(env_cpu(env), false);
362    return cpu_ldub_mmuidx_ra(env, addr, mmu_index, ra);
363}
364
365int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
366{
367    return (int8_t)cpu_ldub_data_ra(env, addr, ra);
368}
369
370uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
371{
372    int mmu_index = cpu_mmu_index(env_cpu(env), false);
373    return cpu_lduw_be_mmuidx_ra(env, addr, mmu_index, ra);
374}
375
376int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
377{
378    return (int16_t)cpu_lduw_be_data_ra(env, addr, ra);
379}
380
381uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
382{
383    int mmu_index = cpu_mmu_index(env_cpu(env), false);
384    return cpu_ldl_be_mmuidx_ra(env, addr, mmu_index, ra);
385}
386
387uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
388{
389    int mmu_index = cpu_mmu_index(env_cpu(env), false);
390    return cpu_ldq_be_mmuidx_ra(env, addr, mmu_index, ra);
391}
392
393uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
394{
395    int mmu_index = cpu_mmu_index(env_cpu(env), false);
396    return cpu_lduw_le_mmuidx_ra(env, addr, mmu_index, ra);
397}
398
399int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
400{
401    return (int16_t)cpu_lduw_le_data_ra(env, addr, ra);
402}
403
404uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
405{
406    int mmu_index = cpu_mmu_index(env_cpu(env), false);
407    return cpu_ldl_le_mmuidx_ra(env, addr, mmu_index, ra);
408}
409
410uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
411{
412    int mmu_index = cpu_mmu_index(env_cpu(env), false);
413    return cpu_ldq_le_mmuidx_ra(env, addr, mmu_index, ra);
414}
415
416void cpu_stb_data_ra(CPUArchState *env, abi_ptr addr,
417                     uint32_t val, uintptr_t ra)
418{
419    int mmu_index = cpu_mmu_index(env_cpu(env), false);
420    cpu_stb_mmuidx_ra(env, addr, val, mmu_index, ra);
421}
422
423void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr,
424                        uint32_t val, uintptr_t ra)
425{
426    int mmu_index = cpu_mmu_index(env_cpu(env), false);
427    cpu_stw_be_mmuidx_ra(env, addr, val, mmu_index, ra);
428}
429
430void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr,
431                        uint32_t val, uintptr_t ra)
432{
433    int mmu_index = cpu_mmu_index(env_cpu(env), false);
434    cpu_stl_be_mmuidx_ra(env, addr, val, mmu_index, ra);
435}
436
437void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr,
438                        uint64_t val, uintptr_t ra)
439{
440    int mmu_index = cpu_mmu_index(env_cpu(env), false);
441    cpu_stq_be_mmuidx_ra(env, addr, val, mmu_index, ra);
442}
443
444void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr,
445                        uint32_t val, uintptr_t ra)
446{
447    int mmu_index = cpu_mmu_index(env_cpu(env), false);
448    cpu_stw_le_mmuidx_ra(env, addr, val, mmu_index, ra);
449}
450
451void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr,
452                        uint32_t val, uintptr_t ra)
453{
454    int mmu_index = cpu_mmu_index(env_cpu(env), false);
455    cpu_stl_le_mmuidx_ra(env, addr, val, mmu_index, ra);
456}
457
458void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr,
459                        uint64_t val, uintptr_t ra)
460{
461    int mmu_index = cpu_mmu_index(env_cpu(env), false);
462    cpu_stq_le_mmuidx_ra(env, addr, val, mmu_index, ra);
463}
464
465/*--------------------------*/
466
467uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr addr)
468{
469    return cpu_ldub_data_ra(env, addr, 0);
470}
471
472int cpu_ldsb_data(CPUArchState *env, abi_ptr addr)
473{
474    return (int8_t)cpu_ldub_data(env, addr);
475}
476
477uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr addr)
478{
479    return cpu_lduw_be_data_ra(env, addr, 0);
480}
481
482int cpu_ldsw_be_data(CPUArchState *env, abi_ptr addr)
483{
484    return (int16_t)cpu_lduw_be_data(env, addr);
485}
486
487uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr addr)
488{
489    return cpu_ldl_be_data_ra(env, addr, 0);
490}
491
492uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr addr)
493{
494    return cpu_ldq_be_data_ra(env, addr, 0);
495}
496
497uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr addr)
498{
499    return cpu_lduw_le_data_ra(env, addr, 0);
500}
501
502int cpu_ldsw_le_data(CPUArchState *env, abi_ptr addr)
503{
504    return (int16_t)cpu_lduw_le_data(env, addr);
505}
506
507uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr addr)
508{
509    return cpu_ldl_le_data_ra(env, addr, 0);
510}
511
512uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr addr)
513{
514    return cpu_ldq_le_data_ra(env, addr, 0);
515}
516
517void cpu_stb_data(CPUArchState *env, abi_ptr addr, uint32_t val)
518{
519    cpu_stb_data_ra(env, addr, val, 0);
520}
521
522void cpu_stw_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
523{
524    cpu_stw_be_data_ra(env, addr, val, 0);
525}
526
527void cpu_stl_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
528{
529    cpu_stl_be_data_ra(env, addr, val, 0);
530}
531
532void cpu_stq_be_data(CPUArchState *env, abi_ptr addr, uint64_t val)
533{
534    cpu_stq_be_data_ra(env, addr, val, 0);
535}
536
537void cpu_stw_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
538{
539    cpu_stw_le_data_ra(env, addr, val, 0);
540}
541
542void cpu_stl_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
543{
544    cpu_stl_le_data_ra(env, addr, val, 0);
545}
546
547void cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
548{
549    cpu_stq_le_data_ra(env, addr, val, 0);
550}
551