1*e4751d34SPhilippe Mathieu-Daudé/* 2*e4751d34SPhilippe Mathieu-Daudé * SPDX-License-Identifier: GPL-2.0-or-later 3*e4751d34SPhilippe Mathieu-Daudé * Atomic extract 64 from 128-bit, AArch64 version. 4*e4751d34SPhilippe Mathieu-Daudé * 5*e4751d34SPhilippe Mathieu-Daudé * Copyright (C) 2023 Linaro, Ltd. 6*e4751d34SPhilippe Mathieu-Daudé */ 7*e4751d34SPhilippe Mathieu-Daudé 8*e4751d34SPhilippe Mathieu-Daudé#ifndef AARCH64_LOAD_EXTRACT_AL16_AL8_H 9*e4751d34SPhilippe Mathieu-Daudé#define AARCH64_LOAD_EXTRACT_AL16_AL8_H 10*e4751d34SPhilippe Mathieu-Daudé 11*e4751d34SPhilippe Mathieu-Daudé#include "host/cpuinfo.h" 12*e4751d34SPhilippe Mathieu-Daudé#include "tcg/debug-assert.h" 13*e4751d34SPhilippe Mathieu-Daudé 14*e4751d34SPhilippe Mathieu-Daudé/** 15*e4751d34SPhilippe Mathieu-Daudé * load_atom_extract_al16_or_al8: 16*e4751d34SPhilippe Mathieu-Daudé * @pv: host address 17*e4751d34SPhilippe Mathieu-Daudé * @s: object size in bytes, @s <= 8. 18*e4751d34SPhilippe Mathieu-Daudé * 19*e4751d34SPhilippe Mathieu-Daudé * Load @s bytes from @pv, when pv % s != 0. If [p, p+s-1] does not 20*e4751d34SPhilippe Mathieu-Daudé * cross an 16-byte boundary then the access must be 16-byte atomic, 21*e4751d34SPhilippe Mathieu-Daudé * otherwise the access must be 8-byte atomic. 22*e4751d34SPhilippe Mathieu-Daudé */ 23*e4751d34SPhilippe Mathieu-Daudéstatic inline uint64_t load_atom_extract_al16_or_al8(void *pv, int s) 24*e4751d34SPhilippe Mathieu-Daudé{ 25*e4751d34SPhilippe Mathieu-Daudé uintptr_t pi = (uintptr_t)pv; 26*e4751d34SPhilippe Mathieu-Daudé __int128_t *ptr_align = (__int128_t *)(pi & ~7); 27*e4751d34SPhilippe Mathieu-Daudé int shr = (pi & 7) * 8; 28*e4751d34SPhilippe Mathieu-Daudé uint64_t l, h; 29*e4751d34SPhilippe Mathieu-Daudé 30*e4751d34SPhilippe Mathieu-Daudé /* 31*e4751d34SPhilippe Mathieu-Daudé * With FEAT_LSE2, LDP is single-copy atomic if 16-byte aligned 32*e4751d34SPhilippe Mathieu-Daudé * and single-copy atomic on the parts if 8-byte aligned. 33*e4751d34SPhilippe Mathieu-Daudé * All we need do is align the pointer mod 8. 34*e4751d34SPhilippe Mathieu-Daudé */ 35*e4751d34SPhilippe Mathieu-Daudé tcg_debug_assert(HAVE_ATOMIC128_RO); 36*e4751d34SPhilippe Mathieu-Daudé asm("ldp %0, %1, %2" : "=r"(l), "=r"(h) : "m"(*ptr_align)); 37*e4751d34SPhilippe Mathieu-Daudé return (l >> shr) | (h << (-shr & 63)); 38*e4751d34SPhilippe Mathieu-Daudé} 39*e4751d34SPhilippe Mathieu-Daudé 40*e4751d34SPhilippe Mathieu-Daudé#endif /* AARCH64_LOAD_EXTRACT_AL16_AL8_H */ 41