xref: /openbmc/qemu/accel/tcg/ldst_common.c.inc (revision 761a9c58)
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,
127                           uint64_t value_low,
128                           uint64_t value_high,
129                           MemOpIdx oi)
130{
131    if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
132        qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
133                                value_low, value_high,
134                                oi, QEMU_PLUGIN_MEM_R);
135    }
136}
137
138uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra)
139{
140    uint8_t ret;
141
142    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_UB);
143    ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
144    plugin_load_cb(env, addr, ret, 0, oi);
145    return ret;
146}
147
148uint16_t cpu_ldw_mmu(CPUArchState *env, abi_ptr addr,
149                     MemOpIdx oi, uintptr_t ra)
150{
151    uint16_t ret;
152
153    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
154    ret = do_ld2_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
155    plugin_load_cb(env, addr, ret, 0, oi);
156    return ret;
157}
158
159uint32_t cpu_ldl_mmu(CPUArchState *env, abi_ptr addr,
160                     MemOpIdx oi, uintptr_t ra)
161{
162    uint32_t ret;
163
164    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
165    ret = do_ld4_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
166    plugin_load_cb(env, addr, ret, 0, oi);
167    return ret;
168}
169
170uint64_t cpu_ldq_mmu(CPUArchState *env, abi_ptr addr,
171                     MemOpIdx oi, uintptr_t ra)
172{
173    uint64_t ret;
174
175    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
176    ret = do_ld8_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
177    plugin_load_cb(env, addr, ret, 0, oi);
178    return ret;
179}
180
181Int128 cpu_ld16_mmu(CPUArchState *env, abi_ptr addr,
182                    MemOpIdx oi, uintptr_t ra)
183{
184    Int128 ret;
185
186    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
187    ret = do_ld16_mmu(env_cpu(env), addr, oi, ra);
188    plugin_load_cb(env, addr, int128_getlo(ret), int128_gethi(ret), oi);
189    return ret;
190}
191
192/*
193 * Store helpers for cpu_ldst.h
194 */
195
196static void plugin_store_cb(CPUArchState *env, abi_ptr addr,
197                            uint64_t value_low,
198                            uint64_t value_high,
199                            MemOpIdx oi)
200{
201    if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
202        qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
203                                value_low, value_high,
204                                oi, QEMU_PLUGIN_MEM_W);
205    }
206}
207
208void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
209                 MemOpIdx oi, uintptr_t retaddr)
210{
211    helper_stb_mmu(env, addr, val, oi, retaddr);
212    plugin_store_cb(env, addr, val, 0, oi);
213}
214
215void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
216                 MemOpIdx oi, uintptr_t retaddr)
217{
218    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
219    do_st2_mmu(env_cpu(env), addr, val, oi, retaddr);
220    plugin_store_cb(env, addr, val, 0, oi);
221}
222
223void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
224                    MemOpIdx oi, uintptr_t retaddr)
225{
226    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
227    do_st4_mmu(env_cpu(env), addr, val, oi, retaddr);
228    plugin_store_cb(env, addr, val, 0, oi);
229}
230
231void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
232                 MemOpIdx oi, uintptr_t retaddr)
233{
234    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
235    do_st8_mmu(env_cpu(env), addr, val, oi, retaddr);
236    plugin_store_cb(env, addr, val, 0, oi);
237}
238
239void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
240                  MemOpIdx oi, uintptr_t retaddr)
241{
242    tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
243    do_st16_mmu(env_cpu(env), addr, val, oi, retaddr);
244    plugin_store_cb(env, addr, int128_getlo(val), int128_gethi(val), oi);
245}
246
247/*
248 * Wrappers of the above
249 */
250
251uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
252                            int mmu_idx, uintptr_t ra)
253{
254    MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
255    return cpu_ldb_mmu(env, addr, oi, ra);
256}
257
258int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
259                       int mmu_idx, uintptr_t ra)
260{
261    return (int8_t)cpu_ldub_mmuidx_ra(env, addr, mmu_idx, ra);
262}
263
264uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
265                               int mmu_idx, uintptr_t ra)
266{
267    MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
268    return cpu_ldw_mmu(env, addr, oi, ra);
269}
270
271int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
272                          int mmu_idx, uintptr_t ra)
273{
274    return (int16_t)cpu_lduw_be_mmuidx_ra(env, addr, mmu_idx, ra);
275}
276
277uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
278                              int mmu_idx, uintptr_t ra)
279{
280    MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
281    return cpu_ldl_mmu(env, addr, oi, ra);
282}
283
284uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
285                              int mmu_idx, uintptr_t ra)
286{
287    MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
288    return cpu_ldq_mmu(env, addr, oi, ra);
289}
290
291uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
292                               int mmu_idx, uintptr_t ra)
293{
294    MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
295    return cpu_ldw_mmu(env, addr, oi, ra);
296}
297
298int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
299                          int mmu_idx, uintptr_t ra)
300{
301    return (int16_t)cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, ra);
302}
303
304uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
305                              int mmu_idx, uintptr_t ra)
306{
307    MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
308    return cpu_ldl_mmu(env, addr, oi, ra);
309}
310
311uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
312                              int mmu_idx, uintptr_t ra)
313{
314    MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
315    return cpu_ldq_mmu(env, addr, oi, ra);
316}
317
318void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
319                       int mmu_idx, uintptr_t ra)
320{
321    MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
322    cpu_stb_mmu(env, addr, val, oi, ra);
323}
324
325void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
326                          int mmu_idx, uintptr_t ra)
327{
328    MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
329    cpu_stw_mmu(env, addr, val, oi, ra);
330}
331
332void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
333                          int mmu_idx, uintptr_t ra)
334{
335    MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
336    cpu_stl_mmu(env, addr, val, oi, ra);
337}
338
339void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
340                          int mmu_idx, uintptr_t ra)
341{
342    MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
343    cpu_stq_mmu(env, addr, val, oi, ra);
344}
345
346void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
347                          int mmu_idx, uintptr_t ra)
348{
349    MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
350    cpu_stw_mmu(env, addr, val, oi, ra);
351}
352
353void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
354                          int mmu_idx, uintptr_t ra)
355{
356    MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
357    cpu_stl_mmu(env, addr, val, oi, ra);
358}
359
360void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
361                          int mmu_idx, uintptr_t ra)
362{
363    MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
364    cpu_stq_mmu(env, addr, val, oi, ra);
365}
366
367/*--------------------------*/
368
369uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
370{
371    int mmu_index = cpu_mmu_index(env_cpu(env), false);
372    return cpu_ldub_mmuidx_ra(env, addr, mmu_index, ra);
373}
374
375int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
376{
377    return (int8_t)cpu_ldub_data_ra(env, addr, ra);
378}
379
380uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
381{
382    int mmu_index = cpu_mmu_index(env_cpu(env), false);
383    return cpu_lduw_be_mmuidx_ra(env, addr, mmu_index, ra);
384}
385
386int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
387{
388    return (int16_t)cpu_lduw_be_data_ra(env, addr, ra);
389}
390
391uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
392{
393    int mmu_index = cpu_mmu_index(env_cpu(env), false);
394    return cpu_ldl_be_mmuidx_ra(env, addr, mmu_index, ra);
395}
396
397uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
398{
399    int mmu_index = cpu_mmu_index(env_cpu(env), false);
400    return cpu_ldq_be_mmuidx_ra(env, addr, mmu_index, ra);
401}
402
403uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
404{
405    int mmu_index = cpu_mmu_index(env_cpu(env), false);
406    return cpu_lduw_le_mmuidx_ra(env, addr, mmu_index, ra);
407}
408
409int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
410{
411    return (int16_t)cpu_lduw_le_data_ra(env, addr, ra);
412}
413
414uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
415{
416    int mmu_index = cpu_mmu_index(env_cpu(env), false);
417    return cpu_ldl_le_mmuidx_ra(env, addr, mmu_index, ra);
418}
419
420uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
421{
422    int mmu_index = cpu_mmu_index(env_cpu(env), false);
423    return cpu_ldq_le_mmuidx_ra(env, addr, mmu_index, ra);
424}
425
426void cpu_stb_data_ra(CPUArchState *env, abi_ptr addr,
427                     uint32_t val, uintptr_t ra)
428{
429    int mmu_index = cpu_mmu_index(env_cpu(env), false);
430    cpu_stb_mmuidx_ra(env, addr, val, mmu_index, ra);
431}
432
433void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr,
434                        uint32_t val, uintptr_t ra)
435{
436    int mmu_index = cpu_mmu_index(env_cpu(env), false);
437    cpu_stw_be_mmuidx_ra(env, addr, val, mmu_index, ra);
438}
439
440void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr,
441                        uint32_t val, uintptr_t ra)
442{
443    int mmu_index = cpu_mmu_index(env_cpu(env), false);
444    cpu_stl_be_mmuidx_ra(env, addr, val, mmu_index, ra);
445}
446
447void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr,
448                        uint64_t val, uintptr_t ra)
449{
450    int mmu_index = cpu_mmu_index(env_cpu(env), false);
451    cpu_stq_be_mmuidx_ra(env, addr, val, mmu_index, ra);
452}
453
454void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr,
455                        uint32_t val, uintptr_t ra)
456{
457    int mmu_index = cpu_mmu_index(env_cpu(env), false);
458    cpu_stw_le_mmuidx_ra(env, addr, val, mmu_index, ra);
459}
460
461void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr,
462                        uint32_t val, uintptr_t ra)
463{
464    int mmu_index = cpu_mmu_index(env_cpu(env), false);
465    cpu_stl_le_mmuidx_ra(env, addr, val, mmu_index, ra);
466}
467
468void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr,
469                        uint64_t val, uintptr_t ra)
470{
471    int mmu_index = cpu_mmu_index(env_cpu(env), false);
472    cpu_stq_le_mmuidx_ra(env, addr, val, mmu_index, ra);
473}
474
475/*--------------------------*/
476
477uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr addr)
478{
479    return cpu_ldub_data_ra(env, addr, 0);
480}
481
482int cpu_ldsb_data(CPUArchState *env, abi_ptr addr)
483{
484    return (int8_t)cpu_ldub_data(env, addr);
485}
486
487uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr addr)
488{
489    return cpu_lduw_be_data_ra(env, addr, 0);
490}
491
492int cpu_ldsw_be_data(CPUArchState *env, abi_ptr addr)
493{
494    return (int16_t)cpu_lduw_be_data(env, addr);
495}
496
497uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr addr)
498{
499    return cpu_ldl_be_data_ra(env, addr, 0);
500}
501
502uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr addr)
503{
504    return cpu_ldq_be_data_ra(env, addr, 0);
505}
506
507uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr addr)
508{
509    return cpu_lduw_le_data_ra(env, addr, 0);
510}
511
512int cpu_ldsw_le_data(CPUArchState *env, abi_ptr addr)
513{
514    return (int16_t)cpu_lduw_le_data(env, addr);
515}
516
517uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr addr)
518{
519    return cpu_ldl_le_data_ra(env, addr, 0);
520}
521
522uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr addr)
523{
524    return cpu_ldq_le_data_ra(env, addr, 0);
525}
526
527void cpu_stb_data(CPUArchState *env, abi_ptr addr, uint32_t val)
528{
529    cpu_stb_data_ra(env, addr, val, 0);
530}
531
532void cpu_stw_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
533{
534    cpu_stw_be_data_ra(env, addr, val, 0);
535}
536
537void cpu_stl_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
538{
539    cpu_stl_be_data_ra(env, addr, val, 0);
540}
541
542void cpu_stq_be_data(CPUArchState *env, abi_ptr addr, uint64_t val)
543{
544    cpu_stq_be_data_ra(env, addr, val, 0);
545}
546
547void cpu_stw_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
548{
549    cpu_stw_le_data_ra(env, addr, val, 0);
550}
551
552void cpu_stl_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
553{
554    cpu_stl_le_data_ra(env, addr, val, 0);
555}
556
557void cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
558{
559    cpu_stq_le_data_ra(env, addr, val, 0);
560}
561