neon_helper.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,458 行 · 第 1/3 页
C
1,458 行
uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x){ int32_t low; int32_t high; low = x; if (low != (int16_t)low) { low = (low >> 31) ^ 0x7fff; SET_QC(); } high = x >> 32; if (high != (int16_t)high) { high = (high >> 31) ^ 0x7fff; SET_QC(); } return (uint16_t)low | (high << 16);}uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x){ if (x > 0xffffffffu) { SET_QC(); return 0xffffffffu; } return x;}uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x){ if ((int64_t)x != (int32_t)x) { SET_QC(); return (x >> 63) ^ 0x7fffffff; } return x;}uint64_t HELPER(neon_widen_u8)(uint32_t x){ uint64_t tmp; uint64_t ret; ret = (uint8_t)x; tmp = (uint8_t)(x >> 8); ret |= tmp << 16; tmp = (uint8_t)(x >> 16); ret |= tmp << 32; tmp = (uint8_t)(x >> 24); ret |= tmp << 48; return ret;}uint64_t HELPER(neon_widen_s8)(uint32_t x){ uint64_t tmp; uint64_t ret; ret = (uint16_t)(int8_t)x; tmp = (uint16_t)(int8_t)(x >> 8); ret |= tmp << 16; tmp = (uint16_t)(int8_t)(x >> 16); ret |= tmp << 32; tmp = (uint16_t)(int8_t)(x >> 24); ret |= tmp << 48; return ret;}uint64_t HELPER(neon_widen_u16)(uint32_t x){ uint64_t high = (uint16_t)(x >> 16); return ((uint16_t)x) | (high << 32);}uint64_t HELPER(neon_widen_s16)(uint32_t x){ uint64_t high = (int16_t)(x >> 16); return ((uint32_t)(int16_t)x) | (high << 32);}uint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b){ uint64_t mask; mask = (a ^ b) & 0x8000800080008000ull; a &= ~0x8000800080008000ull; b &= ~0x8000800080008000ull; return (a + b) ^ mask;}uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b){ uint64_t mask; mask = (a ^ b) & 0x8000000080000000ull; a &= ~0x8000000080000000ull; b &= ~0x8000000080000000ull; return (a + b) ^ mask;}uint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b){ uint64_t tmp; uint64_t tmp2; tmp = a & 0x0000ffff0000ffffull; tmp += (a >> 16) & 0x0000ffff0000ffffull; tmp2 = b & 0xffff0000ffff0000ull; tmp2 += (b << 16) & 0xffff0000ffff0000ull; return ( tmp & 0xffff) | ((tmp >> 16) & 0xffff0000ull) | ((tmp2 << 16) & 0xffff00000000ull) | ( tmp2 & 0xffff000000000000ull);}uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b){ uint32_t low = a + (a >> 32); uint32_t high = b + (b >> 32); return low + ((uint64_t)high << 32);}uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b){ uint64_t mask; mask = (a ^ ~b) & 0x8000800080008000ull; a |= 0x8000800080008000ull; b &= ~0x8000800080008000ull; return (a - b) ^ mask;}uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b){ uint64_t mask; mask = (a ^ ~b) & 0x8000000080000000ull; a |= 0x8000000080000000ull; b &= ~0x8000000080000000ull; return (a - b) ^ mask;}uint64_t HELPER(neon_addl_saturate_s32)(CPUState *env, uint64_t a, uint64_t b){ uint32_t x, y; uint32_t low, high; x = a; y = b; low = x + y; if (((low ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) { SET_QC(); low = ((int32_t)x >> 31) ^ ~SIGNBIT; } x = a >> 32; y = b >> 32; high = x + y; if (((high ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) { SET_QC(); high = ((int32_t)x >> 31) ^ ~SIGNBIT; } return low | ((uint64_t)high << 32);}uint64_t HELPER(neon_addl_saturate_s64)(CPUState *env, uint64_t a, uint64_t b){ uint64_t result; result = a + b; if (((result ^ a) & SIGNBIT64) && !((a ^ b) & SIGNBIT64)) { SET_QC(); result = ((int64_t)a >> 63) ^ ~SIGNBIT64; } return result;}#define DO_ABD(dest, x, y, type) do { \ type tmp_x = x; \ type tmp_y = y; \ dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \ } while(0)uint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_ABD(result, a, b, uint8_t); DO_ABD(tmp, a >> 8, b >> 8, uint8_t); result |= tmp << 16; DO_ABD(tmp, a >> 16, b >> 16, uint8_t); result |= tmp << 32; DO_ABD(tmp, a >> 24, b >> 24, uint8_t); result |= tmp << 48; return result;}uint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_ABD(result, a, b, int8_t); DO_ABD(tmp, a >> 8, b >> 8, int8_t); result |= tmp << 16; DO_ABD(tmp, a >> 16, b >> 16, int8_t); result |= tmp << 32; DO_ABD(tmp, a >> 24, b >> 24, int8_t); result |= tmp << 48; return result;}uint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_ABD(result, a, b, uint16_t); DO_ABD(tmp, a >> 16, b >> 16, uint16_t); return result | (tmp << 32);}uint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_ABD(result, a, b, int16_t); DO_ABD(tmp, a >> 16, b >> 16, int16_t); return result | (tmp << 32);}uint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b){ uint64_t result; DO_ABD(result, a, b, uint32_t); return result;}uint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b){ uint64_t result; DO_ABD(result, a, b, int32_t); return result;}#undef DO_ABD/* Widening multiply. Named type is the source type. */#define DO_MULL(dest, x, y, type1, type2) do { \ type1 tmp_x = x; \ type1 tmp_y = y; \ dest = (type2)((type2)tmp_x * (type2)tmp_y); \ } while(0)uint64_t HELPER(neon_mull_u8)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_MULL(result, a, b, uint8_t, uint16_t); DO_MULL(tmp, a >> 8, b >> 8, uint8_t, uint16_t); result |= tmp << 16; DO_MULL(tmp, a >> 16, b >> 16, uint8_t, uint16_t); result |= tmp << 32; DO_MULL(tmp, a >> 24, b >> 24, uint8_t, uint16_t); result |= tmp << 48; return result;}uint64_t HELPER(neon_mull_s8)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_MULL(result, a, b, int8_t, uint16_t); DO_MULL(tmp, a >> 8, b >> 8, int8_t, uint16_t); result |= tmp << 16; DO_MULL(tmp, a >> 16, b >> 16, int8_t, uint16_t); result |= tmp << 32; DO_MULL(tmp, a >> 24, b >> 24, int8_t, uint16_t); result |= tmp << 48; return result;}uint64_t HELPER(neon_mull_u16)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_MULL(result, a, b, uint16_t, uint32_t); DO_MULL(tmp, a >> 16, b >> 16, uint16_t, uint32_t); return result | (tmp << 32);}uint64_t HELPER(neon_mull_s16)(uint32_t a, uint32_t b){ uint64_t tmp; uint64_t result; DO_MULL(result, a, b, int16_t, uint32_t); DO_MULL(tmp, a >> 16, b >> 16, int16_t, uint32_t); return result | (tmp << 32);}uint64_t HELPER(neon_negl_u16)(uint64_t x){ uint16_t tmp; uint64_t result; result = (uint16_t)-x; tmp = -(x >> 16); result |= (uint64_t)tmp << 16; tmp = -(x >> 32); result |= (uint64_t)tmp << 32; tmp = -(x >> 48); result |= (uint64_t)tmp << 48; return result;}#include <stdio.h>uint64_t HELPER(neon_negl_u32)(uint64_t x){ uint32_t low = -x; uint32_t high = -(x >> 32); return low | ((uint64_t)high << 32);}/* FIXME: There should be a native op for this. */uint64_t HELPER(neon_negl_u64)(uint64_t x){ return -x;}/* Saturnating sign manuipulation. *//* ??? Make these use NEON_VOP1 */#define DO_QABS8(x) do { \ if (x == (int8_t)0x80) { \ x = 0x7f; \ SET_QC(); \ } else if (x < 0) { \ x = -x; \ }} while (0)uint32_t HELPER(neon_qabs_s8)(CPUState *env, uint32_t x){ neon_s8 vec; NEON_UNPACK(neon_s8, vec, x); DO_QABS8(vec.v1); DO_QABS8(vec.v2); DO_QABS8(vec.v3); DO_QABS8(vec.v4); NEON_PACK(neon_s8, x, vec); return x;}#undef DO_QABS8#define DO_QNEG8(x) do { \ if (x == (int8_t)0x80) { \ x = 0x7f; \ SET_QC(); \ } else { \ x = -x; \ }} while (0)uint32_t HELPER(neon_qneg_s8)(CPUState *env, uint32_t x){ neon_s8 vec; NEON_UNPACK(neon_s8, vec, x); DO_QNEG8(vec.v1); DO_QNEG8(vec.v2); DO_QNEG8(vec.v3); DO_QNEG8(vec.v4); NEON_PACK(neon_s8, x, vec); return x;}#undef DO_QNEG8#define DO_QABS16(x) do { \ if (x == (int16_t)0x8000) { \ x = 0x7fff; \ SET_QC(); \ } else if (x < 0) { \ x = -x; \ }} while (0)uint32_t HELPER(neon_qabs_s16)(CPUState *env, uint32_t x){ neon_s16 vec; NEON_UNPACK(neon_s16, vec, x); DO_QABS16(vec.v1); DO_QABS16(vec.v2); NEON_PACK(neon_s16, x, vec); return x;}#undef DO_QABS16#define DO_QNEG16(x) do { \ if (x == (int16_t)0x8000) { \ x = 0x7fff; \ SET_QC(); \ } else { \ x = -x; \ }} while (0)uint32_t HELPER(neon_qneg_s16)(CPUState *env, uint32_t x){ neon_s16 vec; NEON_UNPACK(neon_s16, vec, x); DO_QNEG16(vec.v1); DO_QNEG16(vec.v2); NEON_PACK(neon_s16, x, vec); return x;}#undef DO_QNEG16uint32_t HELPER(neon_qabs_s32)(CPUState *env, uint32_t x){ if (x == SIGNBIT) { SET_QC(); x = ~SIGNBIT; } else if ((int32_t)x < 0) { x = -x; } return x;}uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x){ if (x == SIGNBIT) { SET_QC(); x = ~SIGNBIT; } else { x = -x; } return x;}/* NEON Float helpers. */uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b){ float32 f0 = vfp_itos(a); float32 f1 = vfp_itos(b); return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b;}uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b){ float32 f0 = vfp_itos(a); float32 f1 = vfp_itos(b); return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b;}uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b){ float32 f0 = vfp_itos(a); float32 f1 = vfp_itos(b); return vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1) ? float32_sub(f0, f1, NFS) : float32_sub(f1, f0, NFS));}uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b){ return vfp_stoi(float32_add(vfp_itos(a), vfp_itos(b), NFS));}uint32_t HELPER(neon_sub_f32)(uint32_t a, uint32_t b){ return vfp_stoi(float32_sub(vfp_itos(a), vfp_itos(b), NFS));}uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b){ return vfp_stoi(float32_mul(vfp_itos(a), vfp_itos(b), NFS));}/* Floating point comparisons produce an integer result. */#define NEON_VOP_FCMP(name, cmp) \uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \{ \ if (float32_compare_quiet(vfp_itos(a), vfp_itos(b), NFS) cmp 0) \ return ~0; \ else \ return 0; \}NEON_VOP_FCMP(ceq_f32, ==)NEON_VOP_FCMP(cge_f32, >=)NEON_VOP_FCMP(cgt_f32, >)uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b){ float32 f0 = float32_abs(vfp_itos(a)); float32 f1 = float32_abs(vfp_itos(b)); return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0;}uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b){ float32 f0 = float32_abs(vfp_itos(a)); float32 f1 = float32_abs(vfp_itos(b)); return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?