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