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