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 return cpu_ldub_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 358} 359 360int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 361{ 362 return (int8_t)cpu_ldub_data_ra(env, addr, ra); 363} 364 365uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 366{ 367 return cpu_lduw_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 368} 369 370int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 371{ 372 return (int16_t)cpu_lduw_be_data_ra(env, addr, ra); 373} 374 375uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 376{ 377 return cpu_ldl_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 378} 379 380uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 381{ 382 return cpu_ldq_be_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 383} 384 385uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 386{ 387 return cpu_lduw_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 388} 389 390int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 391{ 392 return (int16_t)cpu_lduw_le_data_ra(env, addr, ra); 393} 394 395uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 396{ 397 return cpu_ldl_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 398} 399 400uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra) 401{ 402 return cpu_ldq_le_mmuidx_ra(env, addr, cpu_mmu_index(env, false), ra); 403} 404 405void cpu_stb_data_ra(CPUArchState *env, abi_ptr addr, 406 uint32_t val, uintptr_t ra) 407{ 408 cpu_stb_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 409} 410 411void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr, 412 uint32_t val, uintptr_t ra) 413{ 414 cpu_stw_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 415} 416 417void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr, 418 uint32_t val, uintptr_t ra) 419{ 420 cpu_stl_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 421} 422 423void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr, 424 uint64_t val, uintptr_t ra) 425{ 426 cpu_stq_be_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 427} 428 429void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr, 430 uint32_t val, uintptr_t ra) 431{ 432 cpu_stw_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 433} 434 435void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr, 436 uint32_t val, uintptr_t ra) 437{ 438 cpu_stl_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 439} 440 441void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr, 442 uint64_t val, uintptr_t ra) 443{ 444 cpu_stq_le_mmuidx_ra(env, addr, val, cpu_mmu_index(env, false), ra); 445} 446 447/*--------------------------*/ 448 449uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr addr) 450{ 451 return cpu_ldub_data_ra(env, addr, 0); 452} 453 454int cpu_ldsb_data(CPUArchState *env, abi_ptr addr) 455{ 456 return (int8_t)cpu_ldub_data(env, addr); 457} 458 459uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr addr) 460{ 461 return cpu_lduw_be_data_ra(env, addr, 0); 462} 463 464int cpu_ldsw_be_data(CPUArchState *env, abi_ptr addr) 465{ 466 return (int16_t)cpu_lduw_be_data(env, addr); 467} 468 469uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr addr) 470{ 471 return cpu_ldl_be_data_ra(env, addr, 0); 472} 473 474uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr addr) 475{ 476 return cpu_ldq_be_data_ra(env, addr, 0); 477} 478 479uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr addr) 480{ 481 return cpu_lduw_le_data_ra(env, addr, 0); 482} 483 484int cpu_ldsw_le_data(CPUArchState *env, abi_ptr addr) 485{ 486 return (int16_t)cpu_lduw_le_data(env, addr); 487} 488 489uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr addr) 490{ 491 return cpu_ldl_le_data_ra(env, addr, 0); 492} 493 494uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr addr) 495{ 496 return cpu_ldq_le_data_ra(env, addr, 0); 497} 498 499void cpu_stb_data(CPUArchState *env, abi_ptr addr, uint32_t val) 500{ 501 cpu_stb_data_ra(env, addr, val, 0); 502} 503 504void cpu_stw_be_data(CPUArchState *env, abi_ptr addr, uint32_t val) 505{ 506 cpu_stw_be_data_ra(env, addr, val, 0); 507} 508 509void cpu_stl_be_data(CPUArchState *env, abi_ptr addr, uint32_t val) 510{ 511 cpu_stl_be_data_ra(env, addr, val, 0); 512} 513 514void cpu_stq_be_data(CPUArchState *env, abi_ptr addr, uint64_t val) 515{ 516 cpu_stq_be_data_ra(env, addr, val, 0); 517} 518 519void cpu_stw_le_data(CPUArchState *env, abi_ptr addr, uint32_t val) 520{ 521 cpu_stw_le_data_ra(env, addr, val, 0); 522} 523 524void cpu_stl_le_data(CPUArchState *env, abi_ptr addr, uint32_t val) 525{ 526 cpu_stl_le_data_ra(env, addr, val, 0); 527} 528 529void cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val) 530{ 531 cpu_stq_le_data_ra(env, addr, val, 0); 532} 533