Commit dd0a0fcd authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg: Add opcodes for vector minmax arithmetic

parent 8afaf050
Loading
Loading
Loading
Loading
+224 −0
Original line number Diff line number Diff line
@@ -1028,3 +1028,227 @@ void HELPER(gvec_ussub64)(void *d, void *a, void *b, uint32_t desc)
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smin8)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int8_t)) {
        int8_t aa = *(int8_t *)(a + i);
        int8_t bb = *(int8_t *)(b + i);
        int8_t dd = aa < bb ? aa : bb;
        *(int8_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smin16)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int16_t)) {
        int16_t aa = *(int16_t *)(a + i);
        int16_t bb = *(int16_t *)(b + i);
        int16_t dd = aa < bb ? aa : bb;
        *(int16_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smin32)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int32_t)) {
        int32_t aa = *(int32_t *)(a + i);
        int32_t bb = *(int32_t *)(b + i);
        int32_t dd = aa < bb ? aa : bb;
        *(int32_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smin64)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int64_t)) {
        int64_t aa = *(int64_t *)(a + i);
        int64_t bb = *(int64_t *)(b + i);
        int64_t dd = aa < bb ? aa : bb;
        *(int64_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smax8)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int8_t)) {
        int8_t aa = *(int8_t *)(a + i);
        int8_t bb = *(int8_t *)(b + i);
        int8_t dd = aa > bb ? aa : bb;
        *(int8_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smax16)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int16_t)) {
        int16_t aa = *(int16_t *)(a + i);
        int16_t bb = *(int16_t *)(b + i);
        int16_t dd = aa > bb ? aa : bb;
        *(int16_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smax32)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int32_t)) {
        int32_t aa = *(int32_t *)(a + i);
        int32_t bb = *(int32_t *)(b + i);
        int32_t dd = aa > bb ? aa : bb;
        *(int32_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_smax64)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(int64_t)) {
        int64_t aa = *(int64_t *)(a + i);
        int64_t bb = *(int64_t *)(b + i);
        int64_t dd = aa > bb ? aa : bb;
        *(int64_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umin8)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
        uint8_t aa = *(uint8_t *)(a + i);
        uint8_t bb = *(uint8_t *)(b + i);
        uint8_t dd = aa < bb ? aa : bb;
        *(uint8_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umin16)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
        uint16_t aa = *(uint16_t *)(a + i);
        uint16_t bb = *(uint16_t *)(b + i);
        uint16_t dd = aa < bb ? aa : bb;
        *(uint16_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umin32)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
        uint32_t aa = *(uint32_t *)(a + i);
        uint32_t bb = *(uint32_t *)(b + i);
        uint32_t dd = aa < bb ? aa : bb;
        *(uint32_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umin64)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
        uint64_t aa = *(uint64_t *)(a + i);
        uint64_t bb = *(uint64_t *)(b + i);
        uint64_t dd = aa < bb ? aa : bb;
        *(uint64_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umax8)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
        uint8_t aa = *(uint8_t *)(a + i);
        uint8_t bb = *(uint8_t *)(b + i);
        uint8_t dd = aa > bb ? aa : bb;
        *(uint8_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umax16)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
        uint16_t aa = *(uint16_t *)(a + i);
        uint16_t bb = *(uint16_t *)(b + i);
        uint16_t dd = aa > bb ? aa : bb;
        *(uint16_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umax32)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
        uint32_t aa = *(uint32_t *)(a + i);
        uint32_t bb = *(uint32_t *)(b + i);
        uint32_t dd = aa > bb ? aa : bb;
        *(uint32_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}

void HELPER(gvec_umax64)(void *d, void *a, void *b, uint32_t desc)
{
    intptr_t oprsz = simd_oprsz(desc);
    intptr_t i;

    for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
        uint64_t aa = *(uint64_t *)(a + i);
        uint64_t bb = *(uint64_t *)(b + i);
        uint64_t dd = aa > bb ? aa : bb;
        *(uint64_t *)(d + i) = dd;
    }
    clear_high(d, oprsz, desc);
}
+20 −0
Original line number Diff line number Diff line
@@ -200,6 +200,26 @@ DEF_HELPER_FLAGS_4(gvec_ussub16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_ussub32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_ussub64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

DEF_HELPER_FLAGS_4(gvec_smin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

DEF_HELPER_FLAGS_4(gvec_smax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_smax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

DEF_HELPER_FLAGS_4(gvec_umin8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umin16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umin32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umin64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

DEF_HELPER_FLAGS_4(gvec_umax8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umax16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umax32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_umax64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)

DEF_HELPER_FLAGS_3(gvec_neg8, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(gvec_neg16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(gvec_neg32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
+10 −0
Original line number Diff line number Diff line
@@ -554,6 +554,16 @@ E.g. VECL=1 -> 64 << 1 -> v128, and VECE=2 -> 1 << 2 -> i32.

  Similarly, v0 = -v1.

* smin_vec:
* umin_vec:

  Similarly, v0 = MIN(v1, v2), for signed and unsigned element types.

* smax_vec:
* umax_vec:

  Similarly, v0 = MAX(v1, v2), for signed and unsigned element types.

* ssadd_vec:
* sssub_vec:
* usadd_vec:
+1 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ typedef enum {
#define TCG_TARGET_HAS_cmp_vec          1
#define TCG_TARGET_HAS_mul_vec          1
#define TCG_TARGET_HAS_sat_vec          0
#define TCG_TARGET_HAS_minmax_vec       0

#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_HAS_MEMORY_BSWAP     1
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ extern bool have_avx2;
#define TCG_TARGET_HAS_cmp_vec          1
#define TCG_TARGET_HAS_mul_vec          1
#define TCG_TARGET_HAS_sat_vec          0
#define TCG_TARGET_HAS_minmax_vec       0

#define TCG_TARGET_deposit_i32_valid(ofs, len) \
    (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
Loading