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 + -
显示快捷键?