1/* 2 * SPDX-License-Identifier: GPL-2.0-or-later 3 * Atomic extract 64 from 128-bit, LoongArch version. 4 * 5 * Copyright (C) 2023 Linaro, Ltd. 6 */ 7 8#ifndef LOONGARCH_LOAD_EXTRACT_AL16_AL8_H 9#define LOONGARCH_LOAD_EXTRACT_AL16_AL8_H 10 11#include "host/cpuinfo.h" 12#include "tcg/debug-assert.h" 13 14/** 15 * load_atom_extract_al16_or_al8: 16 * @pv: host address 17 * @s: object size in bytes, @s <= 8. 18 * 19 * Load @s bytes from @pv, when pv % s != 0. If [p, p+s-1] does not 20 * cross an 16-byte boundary then the access must be 16-byte atomic, 21 * otherwise the access must be 8-byte atomic. 22 */ 23static inline uint64_t load_atom_extract_al16_or_al8(void *pv, int s) 24{ 25 uintptr_t pi = (uintptr_t)pv; 26 Int128 *ptr_align = (Int128 *)(pi & ~7); 27 int shr = (pi & 7) * 8; 28 uint64_t l, h; 29 30 tcg_debug_assert(HAVE_ATOMIC128_RO); 31 asm("vld $vr0, %2, 0\n\t" 32 "vpickve2gr.d %0, $vr0, 0\n\t" 33 "vpickve2gr.d %1, $vr0, 1" 34 : "=r"(l), "=r"(h) : "r"(ptr_align), "m"(*ptr_align) : "f0"); 35 36 return (l >> shr) | (h << (-shr & 63)); 37} 38 39#endif /* LOONGARCH_LOAD_EXTRACT_AL16_AL8_H */ 40