Annotation of qemu/target-arm/op_neon.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * ARM NEON vector operations.
        !             3:  *
        !             4:  * Copyright (c) 2007 CodeSourcery.
        !             5:  * Written by Paul Brook
        !             6:  *
        !             7:  * This code is licenced under the GPL.
        !             8:  */
        !             9: /* Note that for NEON an "l" prefix means it is a wide operation, unlike
        !            10:    scalar arm ops where it means a word size operation.  */
        !            11: 
        !            12: /* ??? NEON ops should probably have their own float status.  */
        !            13: #define NFS &env->vfp.fp_status
        !            14: #define NEON_OP(name) void OPPROTO op_neon_##name (void)
        !            15: 
        !            16: NEON_OP(getreg_T0)
        !            17: {
        !            18:     T0 = *(uint32_t *)((char *) env + PARAM1);
        !            19: }
        !            20: 
        !            21: NEON_OP(getreg_T1)
        !            22: {
        !            23:     T1 = *(uint32_t *)((char *) env + PARAM1);
        !            24: }
        !            25: 
        !            26: NEON_OP(getreg_T2)
        !            27: {
        !            28:     T2 = *(uint32_t *)((char *) env + PARAM1);
        !            29: }
        !            30: 
        !            31: NEON_OP(setreg_T0)
        !            32: {
        !            33:     *(uint32_t *)((char *) env + PARAM1) = T0;
        !            34: }
        !            35: 
        !            36: NEON_OP(setreg_T1)
        !            37: {
        !            38:     *(uint32_t *)((char *) env + PARAM1) = T1;
        !            39: }
        !            40: 
        !            41: NEON_OP(setreg_T2)
        !            42: {
        !            43:     *(uint32_t *)((char *) env + PARAM1) = T2;
        !            44: }
        !            45: 
        !            46: #define NEON_TYPE1(name, type) \
        !            47: typedef struct \
        !            48: { \
        !            49:     type v1; \
        !            50: } neon_##name;
        !            51: #ifdef WORDS_BIGENDIAN
        !            52: #define NEON_TYPE2(name, type) \
        !            53: typedef struct \
        !            54: { \
        !            55:     type v2; \
        !            56:     type v1; \
        !            57: } neon_##name;
        !            58: #define NEON_TYPE4(name, type) \
        !            59: typedef struct \
        !            60: { \
        !            61:     type v4; \
        !            62:     type v3; \
        !            63:     type v2; \
        !            64:     type v1; \
        !            65: } neon_##name;
        !            66: #else
        !            67: #define NEON_TYPE2(name, type) \
        !            68: typedef struct \
        !            69: { \
        !            70:     type v1; \
        !            71:     type v2; \
        !            72: } neon_##name;
        !            73: #define NEON_TYPE4(name, type) \
        !            74: typedef struct \
        !            75: { \
        !            76:     type v1; \
        !            77:     type v2; \
        !            78:     type v3; \
        !            79:     type v4; \
        !            80: } neon_##name;
        !            81: #endif
        !            82: 
        !            83: NEON_TYPE4(s8, int8_t)
        !            84: NEON_TYPE4(u8, uint8_t)
        !            85: NEON_TYPE2(s16, int16_t)
        !            86: NEON_TYPE2(u16, uint16_t)
        !            87: NEON_TYPE1(s32, int32_t)
        !            88: NEON_TYPE1(u32, uint32_t)
        !            89: #undef NEON_TYPE4
        !            90: #undef NEON_TYPE2
        !            91: #undef NEON_TYPE1
        !            92: 
        !            93: /* Copy from a uint32_t to a vector structure type.  */
        !            94: #define NEON_UNPACK(vtype, dest, val) do { \
        !            95:     union { \
        !            96:         vtype v; \
        !            97:         uint32_t i; \
        !            98:     } conv_u; \
        !            99:     conv_u.i = (val); \
        !           100:     dest = conv_u.v; \
        !           101:     } while(0)
        !           102: 
        !           103: /* Copy from a vector structure type to a uint32_t.  */
        !           104: #define NEON_PACK(vtype, dest, val) do { \
        !           105:     union { \
        !           106:         vtype v; \
        !           107:         uint32_t i; \
        !           108:     } conv_u; \
        !           109:     conv_u.v = (val); \
        !           110:     dest = conv_u.i; \
        !           111:     } while(0)
        !           112: 
        !           113: #define NEON_DO1 \
        !           114:     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1);
        !           115: #define NEON_DO2 \
        !           116:     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
        !           117:     NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2);
        !           118: #define NEON_DO4 \
        !           119:     NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
        !           120:     NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2); \
        !           121:     NEON_FN(vdest.v3, vsrc1.v3, vsrc2.v3); \
        !           122:     NEON_FN(vdest.v4, vsrc1.v4, vsrc2.v4);
        !           123: 
        !           124: #define NEON_VOP(name, vtype, n) \
        !           125: NEON_OP(name) \
        !           126: { \
        !           127:     vtype vsrc1; \
        !           128:     vtype vsrc2; \
        !           129:     vtype vdest; \
        !           130:     NEON_UNPACK(vtype, vsrc1, T0); \
        !           131:     NEON_UNPACK(vtype, vsrc2, T1); \
        !           132:     NEON_DO##n; \
        !           133:     NEON_PACK(vtype, T0, vdest); \
        !           134:     FORCE_RET(); \
        !           135: }
        !           136: 
        !           137: #define NEON_VOP1(name, vtype, n) \
        !           138: NEON_OP(name) \
        !           139: { \
        !           140:     vtype vsrc1; \
        !           141:     vtype vdest; \
        !           142:     NEON_UNPACK(vtype, vsrc1, T0); \
        !           143:     NEON_DO##n; \
        !           144:     NEON_PACK(vtype, T0, vdest); \
        !           145:     FORCE_RET(); \
        !           146: }
        !           147: 
        !           148: /* Pairwise operations.  */
        !           149: /* For 32-bit elements each segment only contains a single element, so
        !           150:    the elementwise and pairwise operations are the same.  */
        !           151: #define NEON_PDO2 \
        !           152:     NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
        !           153:     NEON_FN(vdest.v2, vsrc2.v1, vsrc2.v2);
        !           154: #define NEON_PDO4 \
        !           155:     NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
        !           156:     NEON_FN(vdest.v2, vsrc1.v3, vsrc1.v4); \
        !           157:     NEON_FN(vdest.v3, vsrc2.v1, vsrc2.v2); \
        !           158:     NEON_FN(vdest.v4, vsrc2.v3, vsrc2.v4); \
        !           159: 
        !           160: #define NEON_POP(name, vtype, n) \
        !           161: NEON_OP(name) \
        !           162: { \
        !           163:     vtype vsrc1; \
        !           164:     vtype vsrc2; \
        !           165:     vtype vdest; \
        !           166:     NEON_UNPACK(vtype, vsrc1, T0); \
        !           167:     NEON_UNPACK(vtype, vsrc2, T1); \
        !           168:     NEON_PDO##n; \
        !           169:     NEON_PACK(vtype, T0, vdest); \
        !           170:     FORCE_RET(); \
        !           171: }
        !           172: 
        !           173: #define NEON_FN(dest, src1, src2) dest = (src1 + src2) >> 1
        !           174: NEON_VOP(hadd_s8, neon_s8, 4)
        !           175: NEON_VOP(hadd_u8, neon_u8, 4)
        !           176: NEON_VOP(hadd_s16, neon_s16, 2)
        !           177: NEON_VOP(hadd_u16, neon_u16, 2)
        !           178: #undef NEON_FN
        !           179: 
        !           180: NEON_OP(hadd_s32)
        !           181: {
        !           182:     int32_t src1 = T0;
        !           183:     int32_t src2 = T1;
        !           184:     int32_t dest;
        !           185: 
        !           186:     dest = (src1 >> 1) + (src2 >> 1);
        !           187:     if (src1 & src2 & 1)
        !           188:         dest++;
        !           189:     T0 = dest;
        !           190:     FORCE_RET();
        !           191: }
        !           192: 
        !           193: NEON_OP(hadd_u32)
        !           194: {
        !           195:     uint32_t src1 = T0;
        !           196:     uint32_t src2 = T1;
        !           197:     uint32_t dest;
        !           198: 
        !           199:     dest = (src1 >> 1) + (src2 >> 1);
        !           200:     if (src1 & src2 & 1)
        !           201:         dest++;
        !           202:     T0 = dest;
        !           203:     FORCE_RET();
        !           204: }
        !           205: 
        !           206: #define NEON_FN(dest, src1, src2) dest = (src1 + src2 + 1) >> 1
        !           207: NEON_VOP(rhadd_s8, neon_s8, 4)
        !           208: NEON_VOP(rhadd_u8, neon_u8, 4)
        !           209: NEON_VOP(rhadd_s16, neon_s16, 2)
        !           210: NEON_VOP(rhadd_u16, neon_u16, 2)
        !           211: #undef NEON_FN
        !           212: 
        !           213: NEON_OP(rhadd_s32)
        !           214: {
        !           215:     int32_t src1 = T0;
        !           216:     int32_t src2 = T1;
        !           217:     int32_t dest;
        !           218: 
        !           219:     dest = (src1 >> 1) + (src2 >> 1);
        !           220:     if ((src1 | src2) & 1)
        !           221:         dest++;
        !           222:     T0 = dest;
        !           223:     FORCE_RET();
        !           224: }
        !           225: 
        !           226: NEON_OP(rhadd_u32)
        !           227: {
        !           228:     uint32_t src1 = T0;
        !           229:     uint32_t src2 = T1;
        !           230:     uint32_t dest;
        !           231: 
        !           232:     dest = (src1 >> 1) + (src2 >> 1);
        !           233:     if ((src1 | src2) & 1)
        !           234:         dest++;
        !           235:     T0 = dest;
        !           236:     FORCE_RET();
        !           237: }
        !           238: 
        !           239: #define NEON_FN(dest, src1, src2) dest = (src1 - src2) >> 1
        !           240: NEON_VOP(hsub_s8, neon_s8, 4)
        !           241: NEON_VOP(hsub_u8, neon_u8, 4)
        !           242: NEON_VOP(hsub_s16, neon_s16, 2)
        !           243: NEON_VOP(hsub_u16, neon_u16, 2)
        !           244: #undef NEON_FN
        !           245: 
        !           246: NEON_OP(hsub_s32)
        !           247: {
        !           248:     int32_t src1 = T0;
        !           249:     int32_t src2 = T1;
        !           250:     int32_t dest;
        !           251: 
        !           252:     dest = (src1 >> 1) - (src2 >> 1);
        !           253:     if ((~src1) & src2 & 1)
        !           254:         dest--;
        !           255:     T0 = dest;
        !           256:     FORCE_RET();
        !           257: }
        !           258: 
        !           259: NEON_OP(hsub_u32)
        !           260: {
        !           261:     uint32_t src1 = T0;
        !           262:     uint32_t src2 = T1;
        !           263:     uint32_t dest;
        !           264: 
        !           265:     dest = (src1 >> 1) - (src2 >> 1);
        !           266:     if ((~src1) & src2 & 1)
        !           267:         dest--;
        !           268:     T0 = dest;
        !           269:     FORCE_RET();
        !           270: }
        !           271: 
        !           272: /* ??? bsl, bif and bit are all the same op, just with the oparands in a
        !           273:    differnet order.  It's currently easier to have 3 differnt ops than
        !           274:    rearange the operands.  */
        !           275: 
        !           276: /* Bitwise Select.  */
        !           277: NEON_OP(bsl)
        !           278: {
        !           279:     T0 = (T0 & T2) | (T1 & ~T2);
        !           280: }
        !           281: 
        !           282: /* Bitwise Insert If True.  */
        !           283: NEON_OP(bit)
        !           284: {
        !           285:     T0 = (T0 & T1) | (T2 & ~T1);
        !           286: }
        !           287: 
        !           288: /* Bitwise Insert If False.  */
        !           289: NEON_OP(bif)
        !           290: {
        !           291:     T0 = (T2 & T1) | (T0 & ~T1);
        !           292: }
        !           293: 
        !           294: #define NEON_USAT(dest, src1, src2, type) do { \
        !           295:     uint32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
        !           296:     if (tmp != (type)tmp) { \
        !           297:         env->QF = 1; \
        !           298:         dest = ~0; \
        !           299:     } else { \
        !           300:         dest = tmp; \
        !           301:     }} while(0)
        !           302: #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
        !           303: NEON_VOP(qadd_u8, neon_u8, 4)
        !           304: #undef NEON_FN
        !           305: #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
        !           306: NEON_VOP(qadd_u16, neon_u16, 2)
        !           307: #undef NEON_FN
        !           308: #undef NEON_USAT
        !           309: 
        !           310: #define NEON_SSAT(dest, src1, src2, type) do { \
        !           311:     int32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
        !           312:     if (tmp != (type)tmp) { \
        !           313:         env->QF = 1; \
        !           314:         if (src2 > 0) { \
        !           315:             tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
        !           316:         } else { \
        !           317:             tmp = 1 << (sizeof(type) * 8 - 1); \
        !           318:         } \
        !           319:     } \
        !           320:     dest = tmp; \
        !           321:     } while(0)
        !           322: #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
        !           323: NEON_VOP(qadd_s8, neon_s8, 4)
        !           324: #undef NEON_FN
        !           325: #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
        !           326: NEON_VOP(qadd_s16, neon_s16, 2)
        !           327: #undef NEON_FN
        !           328: #undef NEON_SSAT
        !           329: 
        !           330: #define NEON_USAT(dest, src1, src2, type) do { \
        !           331:     uint32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
        !           332:     if (tmp != (type)tmp) { \
        !           333:         env->QF = 1; \
        !           334:         dest = 0; \
        !           335:     } else { \
        !           336:         dest = tmp; \
        !           337:     }} while(0)
        !           338: #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
        !           339: NEON_VOP(qsub_u8, neon_u8, 4)
        !           340: #undef NEON_FN
        !           341: #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
        !           342: NEON_VOP(qsub_u16, neon_u16, 2)
        !           343: #undef NEON_FN
        !           344: #undef NEON_USAT
        !           345: 
        !           346: #define NEON_SSAT(dest, src1, src2, type) do { \
        !           347:     int32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
        !           348:     if (tmp != (type)tmp) { \
        !           349:         env->QF = 1; \
        !           350:         if (src2 < 0) { \
        !           351:             tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
        !           352:         } else { \
        !           353:             tmp = 1 << (sizeof(type) * 8 - 1); \
        !           354:         } \
        !           355:     } \
        !           356:     dest = tmp; \
        !           357:     } while(0)
        !           358: #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
        !           359: NEON_VOP(qsub_s8, neon_s8, 4)
        !           360: #undef NEON_FN
        !           361: #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
        !           362: NEON_VOP(qsub_s16, neon_s16, 2)
        !           363: #undef NEON_FN
        !           364: #undef NEON_SSAT
        !           365: 
        !           366: #define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? ~0 : 0
        !           367: NEON_VOP(cgt_s8, neon_s8, 4)
        !           368: NEON_VOP(cgt_u8, neon_u8, 4)
        !           369: NEON_VOP(cgt_s16, neon_s16, 2)
        !           370: NEON_VOP(cgt_u16, neon_u16, 2)
        !           371: NEON_VOP(cgt_s32, neon_s32, 1)
        !           372: NEON_VOP(cgt_u32, neon_u32, 1)
        !           373: #undef NEON_FN
        !           374: 
        !           375: #define NEON_FN(dest, src1, src2) dest = (src1 >= src2) ? ~0 : 0
        !           376: NEON_VOP(cge_s8, neon_s8, 4)
        !           377: NEON_VOP(cge_u8, neon_u8, 4)
        !           378: NEON_VOP(cge_s16, neon_s16, 2)
        !           379: NEON_VOP(cge_u16, neon_u16, 2)
        !           380: NEON_VOP(cge_s32, neon_s32, 1)
        !           381: NEON_VOP(cge_u32, neon_u32, 1)
        !           382: #undef NEON_FN
        !           383: 
        !           384: #define NEON_FN(dest, src1, src2) do { \
        !           385:     int8_t tmp; \
        !           386:     tmp = (int8_t)src2; \
        !           387:     if (tmp < 0) { \
        !           388:         dest = src1 >> -tmp; \
        !           389:     } else { \
        !           390:         dest = src1 << tmp; \
        !           391:     }} while (0)
        !           392: NEON_VOP(shl_s8, neon_s8, 4)
        !           393: NEON_VOP(shl_u8, neon_u8, 4)
        !           394: NEON_VOP(shl_s16, neon_s16, 2)
        !           395: NEON_VOP(shl_u16, neon_u16, 2)
        !           396: NEON_VOP(shl_s32, neon_s32, 1)
        !           397: NEON_VOP(shl_u32, neon_u32, 1)
        !           398: #undef NEON_FN
        !           399: 
        !           400: NEON_OP(shl_u64)
        !           401: {
        !           402:     int8_t shift = T2;
        !           403:     uint64_t val = T0 | ((uint64_t)T1 << 32);
        !           404:     if (shift < 0) {
        !           405:         val >>= -shift;
        !           406:     } else {
        !           407:         val <<= shift;
        !           408:     }
        !           409:     T0 = val;
        !           410:     T1 = val >> 32;
        !           411:     FORCE_RET();
        !           412: }
        !           413: 
        !           414: NEON_OP(shl_s64)
        !           415: {
        !           416:     int8_t shift = T2;
        !           417:     int64_t val = T0 | ((uint64_t)T1 << 32);
        !           418:     if (shift < 0) {
        !           419:         val >>= -shift;
        !           420:     } else {
        !           421:         val <<= shift;
        !           422:     }
        !           423:     T0 = val;
        !           424:     T1 = val >> 32;
        !           425:     FORCE_RET();
        !           426: }
        !           427: 
        !           428: #define NEON_FN(dest, src1, src2) do { \
        !           429:     int8_t tmp; \
        !           430:     tmp = (int8_t)src1; \
        !           431:     if (tmp < 0) { \
        !           432:         dest = (src2 + (1 << (-1 - tmp))) >> -tmp; \
        !           433:     } else { \
        !           434:         dest = src2 << tmp; \
        !           435:     }} while (0)
        !           436: 
        !           437: NEON_VOP(rshl_s8, neon_s8, 4)
        !           438: NEON_VOP(rshl_u8, neon_u8, 4)
        !           439: NEON_VOP(rshl_s16, neon_s16, 2)
        !           440: NEON_VOP(rshl_u16, neon_u16, 2)
        !           441: NEON_VOP(rshl_s32, neon_s32, 1)
        !           442: NEON_VOP(rshl_u32, neon_u32, 1)
        !           443: #undef NEON_FN
        !           444: 
        !           445: NEON_OP(rshl_u64)
        !           446: {
        !           447:     int8_t shift = T2;
        !           448:     uint64_t val = T0 | ((uint64_t)T1 << 32);
        !           449:     if (shift < 0) {
        !           450:         val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
        !           451:         val >>= -shift;
        !           452:     } else {
        !           453:         val <<= shift;
        !           454:     }
        !           455:     T0 = val;
        !           456:     T1 = val >> 32;
        !           457:     FORCE_RET();
        !           458: }
        !           459: 
        !           460: NEON_OP(rshl_s64)
        !           461: {
        !           462:     int8_t shift = T2;
        !           463:     int64_t val = T0 | ((uint64_t)T1 << 32);
        !           464:     if (shift < 0) {
        !           465:         val = (val + ((int64_t)1 << (-1 - shift))) >> -shift;
        !           466:     } else {
        !           467:         val <<= shift;
        !           468:     }
        !           469:     T0 = val;
        !           470:     T1 = val >> 32;
        !           471:     FORCE_RET();
        !           472: }
        !           473: 
        !           474: #define NEON_FN(dest, src1, src2) do { \
        !           475:     int8_t tmp; \
        !           476:     tmp = (int8_t)src1; \
        !           477:     if (tmp < 0) { \
        !           478:         dest = src2 >> -tmp; \
        !           479:     } else { \
        !           480:         dest = src2 << tmp; \
        !           481:         if ((dest >> tmp) != src2) { \
        !           482:             env->QF = 1; \
        !           483:             dest = ~0; \
        !           484:         } \
        !           485:     }} while (0)
        !           486: NEON_VOP(qshl_s8, neon_s8, 4)
        !           487: NEON_VOP(qshl_s16, neon_s16, 2)
        !           488: NEON_VOP(qshl_s32, neon_s32, 1)
        !           489: #undef NEON_FN
        !           490: 
        !           491: NEON_OP(qshl_s64)
        !           492: {
        !           493:     int8_t shift = T2;
        !           494:     int64_t val = T0 | ((uint64_t)T1 << 32);
        !           495:     if (shift < 0) {
        !           496:         val >>= -shift;
        !           497:     } else {
        !           498:         int64_t tmp = val;
        !           499:         val <<= shift;
        !           500:         if ((val >> shift) != tmp) {
        !           501:             env->QF = 1;
        !           502:             val = (tmp >> 63) ^ 0x7fffffffffffffffULL;
        !           503:         }
        !           504:     }
        !           505:     T0 = val;
        !           506:     T1 = val >> 32;
        !           507:     FORCE_RET();
        !           508: }
        !           509: 
        !           510: #define NEON_FN(dest, src1, src2) do { \
        !           511:     int8_t tmp; \
        !           512:     tmp = (int8_t)src1; \
        !           513:     if (tmp < 0) { \
        !           514:         dest = src2 >> -tmp; \
        !           515:     } else { \
        !           516:         dest = src2 << tmp; \
        !           517:         if ((dest >> tmp) != src2) { \
        !           518:             env->QF = 1; \
        !           519:             dest = src2 >> 31; \
        !           520:         } \
        !           521:     }} while (0)
        !           522: NEON_VOP(qshl_u8, neon_u8, 4)
        !           523: NEON_VOP(qshl_u16, neon_u16, 2)
        !           524: NEON_VOP(qshl_u32, neon_u32, 1)
        !           525: #undef NEON_FN
        !           526: 
        !           527: NEON_OP(qshl_u64)
        !           528: {
        !           529:     int8_t shift = T2;
        !           530:     uint64_t val = T0 | ((uint64_t)T1 << 32);
        !           531:     if (shift < 0) {
        !           532:         val >>= -shift;
        !           533:     } else {
        !           534:         uint64_t tmp = val;
        !           535:         val <<= shift;
        !           536:         if ((val >> shift) != tmp) {
        !           537:             env->QF = 1;
        !           538:             val = ~(uint64_t)0;
        !           539:         }
        !           540:     }
        !           541:     T0 = val;
        !           542:     T1 = val >> 32;
        !           543:     FORCE_RET();
        !           544: }
        !           545: 
        !           546: #define NEON_FN(dest, src1, src2) do { \
        !           547:     int8_t tmp; \
        !           548:     tmp = (int8_t)src1; \
        !           549:     if (tmp < 0) { \
        !           550:         dest = (src2 + (1 << (-1 - tmp))) >> -tmp; \
        !           551:     } else { \
        !           552:         dest = src2 << tmp; \
        !           553:         if ((dest >> tmp) != src2) { \
        !           554:             dest = ~0; \
        !           555:         } \
        !           556:     }} while (0)
        !           557: NEON_VOP(qrshl_s8, neon_s8, 4)
        !           558: NEON_VOP(qrshl_s16, neon_s16, 2)
        !           559: NEON_VOP(qrshl_s32, neon_s32, 1)
        !           560: #undef NEON_FN
        !           561: 
        !           562: #define NEON_FN(dest, src1, src2) do { \
        !           563:     int8_t tmp; \
        !           564:     tmp = (int8_t)src1; \
        !           565:     if (tmp < 0) { \
        !           566:         dest = (src2 + (1 << (-1 - tmp))) >> -tmp; \
        !           567:     } else { \
        !           568:         dest = src2 << tmp; \
        !           569:         if ((dest >> tmp) != src2) { \
        !           570:             env->QF = 1; \
        !           571:             dest = src2 >> 31; \
        !           572:         } \
        !           573:     }} while (0)
        !           574: NEON_VOP(qrshl_u8, neon_u8, 4)
        !           575: NEON_VOP(qrshl_u16, neon_u16, 2)
        !           576: NEON_VOP(qrshl_u32, neon_u32, 1)
        !           577: #undef NEON_FN
        !           578: 
        !           579: #define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
        !           580: NEON_VOP(max_s8, neon_s8, 4)
        !           581: NEON_VOP(max_u8, neon_u8, 4)
        !           582: NEON_VOP(max_s16, neon_s16, 2)
        !           583: NEON_VOP(max_u16, neon_u16, 2)
        !           584: NEON_VOP(max_s32, neon_s32, 1)
        !           585: NEON_VOP(max_u32, neon_u32, 1)
        !           586: NEON_POP(pmax_s8, neon_s8, 4)
        !           587: NEON_POP(pmax_u8, neon_u8, 4)
        !           588: NEON_POP(pmax_s16, neon_s16, 2)
        !           589: NEON_POP(pmax_u16, neon_u16, 2)
        !           590: #undef NEON_FN
        !           591: 
        !           592: NEON_OP(max_f32)
        !           593: {
        !           594:     float32 f0 = vfp_itos(T0);
        !           595:     float32 f1 = vfp_itos(T1);
        !           596:     T0 = (float32_compare_quiet(f0, f1, NFS) == 1) ? T0 : T1;
        !           597:     FORCE_RET();
        !           598: }
        !           599: 
        !           600: #define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
        !           601: NEON_VOP(min_s8, neon_s8, 4)
        !           602: NEON_VOP(min_u8, neon_u8, 4)
        !           603: NEON_VOP(min_s16, neon_s16, 2)
        !           604: NEON_VOP(min_u16, neon_u16, 2)
        !           605: NEON_VOP(min_s32, neon_s32, 1)
        !           606: NEON_VOP(min_u32, neon_u32, 1)
        !           607: NEON_POP(pmin_s8, neon_s8, 4)
        !           608: NEON_POP(pmin_u8, neon_u8, 4)
        !           609: NEON_POP(pmin_s16, neon_s16, 2)
        !           610: NEON_POP(pmin_u16, neon_u16, 2)
        !           611: #undef NEON_FN
        !           612: 
        !           613: NEON_OP(min_f32)
        !           614: {
        !           615:     float32 f0 = vfp_itos(T0);
        !           616:     float32 f1 = vfp_itos(T1);
        !           617:     T0 = (float32_compare_quiet(f0, f1, NFS) == -1) ? T0 : T1;
        !           618:     FORCE_RET();
        !           619: }
        !           620: 
        !           621: #define NEON_FN(dest, src1, src2) \
        !           622:     dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
        !           623: NEON_VOP(abd_s8, neon_s8, 4)
        !           624: NEON_VOP(abd_u8, neon_u8, 4)
        !           625: NEON_VOP(abd_s16, neon_s16, 2)
        !           626: NEON_VOP(abd_u16, neon_u16, 2)
        !           627: NEON_VOP(abd_s32, neon_s32, 1)
        !           628: NEON_VOP(abd_u32, neon_u32, 1)
        !           629: #undef NEON_FN
        !           630: 
        !           631: NEON_OP(abd_f32)
        !           632: {
        !           633:     float32 f0 = vfp_itos(T0);
        !           634:     float32 f1 = vfp_itos(T1);
        !           635:     T0 = vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1)
        !           636:                   ? float32_sub(f0, f1, NFS)
        !           637:                   : float32_sub(f1, f0, NFS));
        !           638:     FORCE_RET();
        !           639: }
        !           640: 
        !           641: #define NEON_FN(dest, src1, src2) dest = src1 + src2
        !           642: NEON_VOP(add_u8, neon_u8, 4)
        !           643: NEON_VOP(add_u16, neon_u16, 2)
        !           644: NEON_POP(padd_u8, neon_u8, 4)
        !           645: NEON_POP(padd_u16, neon_u16, 2)
        !           646: #undef NEON_FN
        !           647: 
        !           648: NEON_OP(add_f32)
        !           649: {
        !           650:     T0 = vfp_stoi(float32_add(vfp_itos(T0), vfp_itos(T1), NFS));
        !           651:     FORCE_RET();
        !           652: }
        !           653: 
        !           654: #define NEON_FN(dest, src1, src2) dest = src1 - src2
        !           655: NEON_VOP(sub_u8, neon_u8, 4)
        !           656: NEON_VOP(sub_u16, neon_u16, 2)
        !           657: #undef NEON_FN
        !           658: 
        !           659: NEON_OP(sub_f32)
        !           660: {
        !           661:     T0 = vfp_stoi(float32_sub(vfp_itos(T0), vfp_itos(T1), NFS));
        !           662:     FORCE_RET();
        !           663: }
        !           664: 
        !           665: #define NEON_FN(dest, src1, src2) dest = src2 - src1
        !           666: NEON_VOP(rsb_u8, neon_u8, 4)
        !           667: NEON_VOP(rsb_u16, neon_u16, 2)
        !           668: #undef NEON_FN
        !           669: 
        !           670: NEON_OP(rsb_f32)
        !           671: {
        !           672:     T0 = vfp_stoi(float32_sub(vfp_itos(T1), vfp_itos(T0), NFS));
        !           673:     FORCE_RET();
        !           674: }
        !           675: 
        !           676: #define NEON_FN(dest, src1, src2) dest = src1 * src2
        !           677: NEON_VOP(mul_u8, neon_u8, 4)
        !           678: NEON_VOP(mul_u16, neon_u16, 2)
        !           679: #undef NEON_FN
        !           680: 
        !           681: NEON_OP(mul_f32)
        !           682: {
        !           683:     T0 = vfp_stoi(float32_mul(vfp_itos(T0), vfp_itos(T1), NFS));
        !           684:     FORCE_RET();
        !           685: }
        !           686: 
        !           687: NEON_OP(mul_p8)
        !           688: {
        !           689:     T0 = helper_neon_mul_p8(T0, T1);
        !           690: }
        !           691: 
        !           692: #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
        !           693: NEON_VOP(tst_u8, neon_u8, 4)
        !           694: NEON_VOP(tst_u16, neon_u16, 2)
        !           695: NEON_VOP(tst_u32, neon_u32, 1)
        !           696: #undef NEON_FN
        !           697: 
        !           698: #define NEON_FN(dest, src1, src2) dest = (src1 == src2) ? -1 : 0
        !           699: NEON_VOP(ceq_u8, neon_u8, 4)
        !           700: NEON_VOP(ceq_u16, neon_u16, 2)
        !           701: NEON_VOP(ceq_u32, neon_u32, 1)
        !           702: #undef NEON_FN
        !           703: 
        !           704: #define NEON_QDMULH16(dest, src1, src2, round) do { \
        !           705:     uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \
        !           706:     if ((tmp ^ (tmp << 1)) & SIGNBIT) { \
        !           707:         env->QF = 1; \
        !           708:         tmp = (tmp >> 31) ^ ~SIGNBIT; \
        !           709:     } \
        !           710:     tmp <<= 1; \
        !           711:     if (round) { \
        !           712:         int32_t old = tmp; \
        !           713:         tmp += 1 << 15; \
        !           714:         if ((int32_t)tmp < old) { \
        !           715:             env->QF = 1; \
        !           716:             tmp = SIGNBIT - 1; \
        !           717:         } \
        !           718:     } \
        !           719:     dest = tmp >> 16; \
        !           720:     } while(0)
        !           721: #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 0)
        !           722: NEON_VOP(qdmulh_s16, neon_s16, 2)
        !           723: #undef NEON_FN
        !           724: #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 1)
        !           725: NEON_VOP(qrdmulh_s16, neon_s16, 2)
        !           726: #undef NEON_FN
        !           727: #undef NEON_QDMULH16
        !           728: 
        !           729: #define SIGNBIT64 ((uint64_t)1 << 63)
        !           730: #define NEON_QDMULH32(dest, src1, src2, round) do { \
        !           731:     uint64_t tmp = (int64_t)(int32_t) src1 * (int32_t) src2; \
        !           732:     if ((tmp ^ (tmp << 1)) & SIGNBIT64) { \
        !           733:         env->QF = 1; \
        !           734:         tmp = (tmp >> 63) ^ ~SIGNBIT64; \
        !           735:     } else { \
        !           736:         tmp <<= 1; \
        !           737:     } \
        !           738:     if (round) { \
        !           739:         int64_t old = tmp; \
        !           740:         tmp += (int64_t)1 << 31; \
        !           741:         if ((int64_t)tmp < old) { \
        !           742:             env->QF = 1; \
        !           743:             tmp = SIGNBIT64 - 1; \
        !           744:         } \
        !           745:     } \
        !           746:     dest = tmp >> 32; \
        !           747:     } while(0)
        !           748: #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 0)
        !           749: NEON_VOP(qdmulh_s32, neon_s32, 1)
        !           750: #undef NEON_FN
        !           751: #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 1)
        !           752: NEON_VOP(qrdmulh_s32, neon_s32, 1)
        !           753: #undef NEON_FN
        !           754: #undef NEON_QDMULH32
        !           755: 
        !           756: NEON_OP(recps_f32)
        !           757: {
        !           758:     T0 = vfp_stoi(helper_recps_f32(vfp_itos(T0), vfp_itos(T1)));
        !           759:     FORCE_RET();
        !           760: }
        !           761: 
        !           762: NEON_OP(rsqrts_f32)
        !           763: {
        !           764:     T0 = vfp_stoi(helper_rsqrts_f32(vfp_itos(T0), vfp_itos(T1)));
        !           765:     FORCE_RET();
        !           766: }
        !           767: 
        !           768: /* Floating point comparisons produce an integer result.  */
        !           769: #define NEON_VOP_FCMP(name, cmp) \
        !           770: NEON_OP(name) \
        !           771: { \
        !           772:     if (float32_compare_quiet(vfp_itos(T0), vfp_itos(T1), NFS) cmp 0) \
        !           773:         T0 = -1; \
        !           774:     else \
        !           775:         T0 = 0; \
        !           776:     FORCE_RET(); \
        !           777: }
        !           778: 
        !           779: NEON_VOP_FCMP(ceq_f32, ==)
        !           780: NEON_VOP_FCMP(cge_f32, >=)
        !           781: NEON_VOP_FCMP(cgt_f32, >)
        !           782: 
        !           783: NEON_OP(acge_f32)
        !           784: {
        !           785:     float32 f0 = float32_abs(vfp_itos(T0));
        !           786:     float32 f1 = float32_abs(vfp_itos(T1));
        !           787:     T0 = (float32_compare_quiet(f0, f1,NFS) >= 0) ? -1 : 0;
        !           788:     FORCE_RET();
        !           789: }
        !           790: 
        !           791: NEON_OP(acgt_f32)
        !           792: {
        !           793:     float32 f0 = float32_abs(vfp_itos(T0));
        !           794:     float32 f1 = float32_abs(vfp_itos(T1));
        !           795:     T0 = (float32_compare_quiet(f0, f1, NFS) > 0) ? -1 : 0;
        !           796:     FORCE_RET();
        !           797: }
        !           798: 
        !           799: /* Narrowing instructions.  The named type is the destination type.  */
        !           800: NEON_OP(narrow_u8)
        !           801: {
        !           802:     T0 = (T0 & 0xff) | ((T0 >> 8) & 0xff00)
        !           803:          | ((T1 << 16) & 0xff0000) | (T1 << 24);
        !           804:     FORCE_RET();
        !           805: }
        !           806: 
        !           807: NEON_OP(narrow_sat_u8)
        !           808: {
        !           809:     neon_u16 src;
        !           810:     neon_u8 dest;
        !           811: #define SAT8(d, s) \
        !           812:     if (s > 0xff) { \
        !           813:         d = 0xff; \
        !           814:         env->QF = 1; \
        !           815:     } else  { \
        !           816:         d = s; \
        !           817:     }
        !           818: 
        !           819:     NEON_UNPACK(neon_u16, src, T0);
        !           820:     SAT8(dest.v1, src.v1);
        !           821:     SAT8(dest.v2, src.v2);
        !           822:     NEON_UNPACK(neon_u16, src, T1);
        !           823:     SAT8(dest.v3, src.v1);
        !           824:     SAT8(dest.v4, src.v2);
        !           825:     NEON_PACK(neon_u8, T0, dest);
        !           826:     FORCE_RET();
        !           827: #undef SAT8
        !           828: }
        !           829: 
        !           830: NEON_OP(narrow_sat_s8)
        !           831: {
        !           832:     neon_s16 src;
        !           833:     neon_s8 dest;
        !           834: #define SAT8(d, s) \
        !           835:     if (s != (uint8_t)s) { \
        !           836:         d = (s >> 15) ^ 0x7f; \
        !           837:         env->QF = 1; \
        !           838:     } else  { \
        !           839:         d = s; \
        !           840:     }
        !           841: 
        !           842:     NEON_UNPACK(neon_s16, src, T0);
        !           843:     SAT8(dest.v1, src.v1);
        !           844:     SAT8(dest.v2, src.v2);
        !           845:     NEON_UNPACK(neon_s16, src, T1);
        !           846:     SAT8(dest.v3, src.v1);
        !           847:     SAT8(dest.v4, src.v2);
        !           848:     NEON_PACK(neon_s8, T0, dest);
        !           849:     FORCE_RET();
        !           850: #undef SAT8
        !           851: }
        !           852: 
        !           853: NEON_OP(narrow_u16)
        !           854: {
        !           855:     T0 = (T0 & 0xffff) | (T1 << 16);
        !           856: }
        !           857: 
        !           858: NEON_OP(narrow_sat_u16)
        !           859: {
        !           860:     if (T0 > 0xffff) {
        !           861:         T0 = 0xffff;
        !           862:         env->QF = 1;
        !           863:     }
        !           864:     if (T1 > 0xffff) {
        !           865:         T1 = 0xffff;
        !           866:         env->QF = 1;
        !           867:     }
        !           868:     T0 |= T1 << 16;
        !           869:     FORCE_RET();
        !           870: }
        !           871: 
        !           872: NEON_OP(narrow_sat_s16)
        !           873: {
        !           874:     if ((int32_t)T0 != (int16_t)T0) {
        !           875:         T0 = ((int32_t)T0 >> 31) ^ 0x7fff;
        !           876:         env->QF = 1;
        !           877:     }
        !           878:     if ((int32_t)T1 != (int16_t) T1) {
        !           879:         T1 = ((int32_t)T1 >> 31) ^ 0x7fff;
        !           880:         env->QF = 1;
        !           881:     }
        !           882:     T0 = (uint16_t)T0 | (T1 << 16);
        !           883:     FORCE_RET();
        !           884: }
        !           885: 
        !           886: NEON_OP(narrow_sat_u32)
        !           887: {
        !           888:     if (T1) {
        !           889:         T0 = 0xffffffffu;
        !           890:         env->QF = 1;
        !           891:     }
        !           892:     FORCE_RET();
        !           893: }
        !           894: 
        !           895: NEON_OP(narrow_sat_s32)
        !           896: {
        !           897:     int32_t sign = (int32_t)T1 >> 31;
        !           898: 
        !           899:     if ((int32_t)T1 != sign) {
        !           900:         T0 = sign ^ 0x7fffffff;
        !           901:         env->QF = 1;
        !           902:     }
        !           903:     FORCE_RET();
        !           904: }
        !           905: 
        !           906: /* Narrowing instructions.  Named type is the narrow type.  */
        !           907: NEON_OP(narrow_high_u8)
        !           908: {
        !           909:     T0 = ((T0 >> 8) & 0xff) | ((T0 >> 16) & 0xff00)
        !           910:         | ((T1 << 8) & 0xff0000) | (T1 & 0xff000000);
        !           911:     FORCE_RET();
        !           912: }
        !           913: 
        !           914: NEON_OP(narrow_high_u16)
        !           915: {
        !           916:     T0 = (T0 >> 16) | (T1 & 0xffff0000);
        !           917:     FORCE_RET();
        !           918: }
        !           919: 
        !           920: NEON_OP(narrow_high_round_u8)
        !           921: {
        !           922:     T0 = (((T0 + 0x80) >> 8) & 0xff) | (((T0 + 0x800000) >> 16) & 0xff00)
        !           923:         | (((T1 + 0x80) << 8) & 0xff0000) | ((T1 + 0x800000) & 0xff000000);
        !           924:     FORCE_RET();
        !           925: }
        !           926: 
        !           927: NEON_OP(narrow_high_round_u16)
        !           928: {
        !           929:     T0 = ((T0 + 0x8000) >> 16) | ((T1 + 0x8000) & 0xffff0000);
        !           930:     FORCE_RET();
        !           931: }
        !           932: 
        !           933: NEON_OP(narrow_high_round_u32)
        !           934: {
        !           935:     if (T0 >= 0x80000000u)
        !           936:         T0 = T1 + 1;
        !           937:     else
        !           938:         T0 = T1;
        !           939:     FORCE_RET();
        !           940: }
        !           941: 
        !           942: /* Widening instructions.  Named type is source type.  */
        !           943: NEON_OP(widen_s8)
        !           944: {
        !           945:     uint32_t src;
        !           946: 
        !           947:     src = T0;
        !           948:     T0 = (uint16_t)(int8_t)src | ((int8_t)(src >> 8) << 16);
        !           949:     T1 = (uint16_t)(int8_t)(src >> 16) | ((int8_t)(src >> 24) << 16);
        !           950: }
        !           951: 
        !           952: NEON_OP(widen_u8)
        !           953: {
        !           954:     T1 = ((T0 >> 8) & 0xff0000) | ((T0 >> 16) & 0xff);
        !           955:     T0 = ((T0 << 8) & 0xff0000) | (T0 & 0xff);
        !           956: }
        !           957: 
        !           958: NEON_OP(widen_s16)
        !           959: {
        !           960:     int32_t src;
        !           961: 
        !           962:     src = T0;
        !           963:     T0 = (int16_t)src;
        !           964:     T1 = src >> 16;
        !           965: }
        !           966: 
        !           967: NEON_OP(widen_u16)
        !           968: {
        !           969:     T1 = T0 >> 16;
        !           970:     T0 &= 0xffff;
        !           971: }
        !           972: 
        !           973: NEON_OP(widen_s32)
        !           974: {
        !           975:     T1 = (int32_t)T0 >> 31;
        !           976:     FORCE_RET();
        !           977: }
        !           978: 
        !           979: NEON_OP(widen_high_u8)
        !           980: {
        !           981:     T1 = (T0 & 0xff000000) | ((T0 >> 8) & 0xff00);
        !           982:     T0 = ((T0 << 16) & 0xff000000) | ((T0 << 8) & 0xff00);
        !           983: }
        !           984: 
        !           985: NEON_OP(widen_high_u16)
        !           986: {
        !           987:     T1 = T0 & 0xffff0000;
        !           988:     T0 <<= 16;
        !           989: }
        !           990: 
        !           991: /* Long operations.  The type is the wide type.  */
        !           992: NEON_OP(shll_u16)
        !           993: {
        !           994:     int shift = PARAM1;
        !           995:     uint32_t mask;
        !           996: 
        !           997:     mask = 0xffff >> (16 - shift);
        !           998:     mask |= mask << 16;
        !           999:     mask = ~mask;
        !          1000: 
        !          1001:     T0 = (T0 << shift) & mask;
        !          1002:     T1 = (T1 << shift) & mask;
        !          1003:     FORCE_RET();
        !          1004: }
        !          1005: 
        !          1006: NEON_OP(shll_u64)
        !          1007: {
        !          1008:     int shift = PARAM1;
        !          1009: 
        !          1010:     T1 <<= shift;
        !          1011:     T1 |= T0 >> (32 - shift);
        !          1012:     T0 <<= shift;
        !          1013:     FORCE_RET();
        !          1014: }
        !          1015: 
        !          1016: NEON_OP(addl_u16)
        !          1017: {
        !          1018:     uint32_t tmp;
        !          1019:     uint32_t high;
        !          1020: 
        !          1021:     tmp = env->vfp.scratch[0];
        !          1022:     high = (T0 >> 16) + (tmp >> 16);
        !          1023:     T0 = (uint16_t)(T0 + tmp);
        !          1024:     T0 |= (high << 16);
        !          1025:     tmp = env->vfp.scratch[1];
        !          1026:     high = (T1 >> 16) + (tmp >> 16);
        !          1027:     T1 = (uint16_t)(T1 + tmp);
        !          1028:     T1 |= (high << 16);
        !          1029:     FORCE_RET();
        !          1030: }
        !          1031: 
        !          1032: NEON_OP(addl_u32)
        !          1033: {
        !          1034:     T0 += env->vfp.scratch[0];
        !          1035:     T1 += env->vfp.scratch[1];
        !          1036:     FORCE_RET();
        !          1037: }
        !          1038: 
        !          1039: NEON_OP(addl_u64)
        !          1040: {
        !          1041:     uint64_t tmp;
        !          1042:     tmp = T0 | ((uint64_t)T1 << 32);
        !          1043:     tmp += env->vfp.scratch[0];
        !          1044:     tmp += (uint64_t)env->vfp.scratch[1] << 32;
        !          1045:     T0 = tmp;
        !          1046:     T1 = tmp >> 32;
        !          1047:     FORCE_RET();
        !          1048: }
        !          1049: 
        !          1050: NEON_OP(subl_u16)
        !          1051: {
        !          1052:     uint32_t tmp;
        !          1053:     uint32_t high;
        !          1054: 
        !          1055:     tmp = env->vfp.scratch[0];
        !          1056:     high = (T0 >> 16) - (tmp >> 16);
        !          1057:     T0 = (uint16_t)(T0 - tmp);
        !          1058:     T0 |= (high << 16);
        !          1059:     tmp = env->vfp.scratch[1];
        !          1060:     high = (T1 >> 16) - (tmp >> 16);
        !          1061:     T1 = (uint16_t)(T1 - tmp);
        !          1062:     T1 |= (high << 16);
        !          1063:     FORCE_RET();
        !          1064: }
        !          1065: 
        !          1066: NEON_OP(subl_u32)
        !          1067: {
        !          1068:     T0 -= env->vfp.scratch[0];
        !          1069:     T1 -= env->vfp.scratch[1];
        !          1070:     FORCE_RET();
        !          1071: }
        !          1072: 
        !          1073: NEON_OP(subl_u64)
        !          1074: {
        !          1075:     uint64_t tmp;
        !          1076:     tmp = T0 | ((uint64_t)T1 << 32);
        !          1077:     tmp -= env->vfp.scratch[0];
        !          1078:     tmp -= (uint64_t)env->vfp.scratch[1] << 32;
        !          1079:     T0 = tmp;
        !          1080:     T1 = tmp >> 32;
        !          1081:     FORCE_RET();
        !          1082: }
        !          1083: 
        !          1084: #define DO_ABD(dest, x, y, type) do { \
        !          1085:     type tmp_x = x; \
        !          1086:     type tmp_y = y; \
        !          1087:     dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \
        !          1088:     } while(0)
        !          1089: 
        !          1090: NEON_OP(abdl_u16)
        !          1091: {
        !          1092:     uint32_t tmp;
        !          1093:     uint32_t low;
        !          1094:     uint32_t high;
        !          1095: 
        !          1096:     DO_ABD(low, T0, T1, uint8_t);
        !          1097:     DO_ABD(tmp, T0 >> 8, T1 >> 8, uint8_t);
        !          1098:     low |= tmp << 16;
        !          1099:     DO_ABD(high, T0 >> 16, T1 >> 16, uint8_t);
        !          1100:     DO_ABD(tmp, T0 >> 24, T1 >> 24, uint8_t);
        !          1101:     high |= tmp << 16;
        !          1102:     T0 = low;
        !          1103:     T1 = high;
        !          1104:     FORCE_RET();
        !          1105: }
        !          1106: 
        !          1107: NEON_OP(abdl_s16)
        !          1108: {
        !          1109:     uint32_t tmp;
        !          1110:     uint32_t low;
        !          1111:     uint32_t high;
        !          1112: 
        !          1113:     DO_ABD(low, T0, T1, int8_t);
        !          1114:     DO_ABD(tmp, T0 >> 8, T1 >> 8, int8_t);
        !          1115:     low |= tmp << 16;
        !          1116:     DO_ABD(high, T0 >> 16, T1 >> 16, int8_t);
        !          1117:     DO_ABD(tmp, T0 >> 24, T1 >> 24, int8_t);
        !          1118:     high |= tmp << 16;
        !          1119:     T0 = low;
        !          1120:     T1 = high;
        !          1121:     FORCE_RET();
        !          1122: }
        !          1123: 
        !          1124: NEON_OP(abdl_u32)
        !          1125: {
        !          1126:     uint32_t low;
        !          1127:     uint32_t high;
        !          1128: 
        !          1129:     DO_ABD(low, T0, T1, uint16_t);
        !          1130:     DO_ABD(high, T0 >> 16, T1 >> 16, uint16_t);
        !          1131:     T0 = low;
        !          1132:     T1 = high;
        !          1133:     FORCE_RET();
        !          1134: }
        !          1135: 
        !          1136: NEON_OP(abdl_s32)
        !          1137: {
        !          1138:     uint32_t low;
        !          1139:     uint32_t high;
        !          1140: 
        !          1141:     DO_ABD(low, T0, T1, int16_t);
        !          1142:     DO_ABD(high, T0 >> 16, T1 >> 16, int16_t);
        !          1143:     T0 = low;
        !          1144:     T1 = high;
        !          1145:     FORCE_RET();
        !          1146: }
        !          1147: 
        !          1148: NEON_OP(abdl_u64)
        !          1149: {
        !          1150:     DO_ABD(T0, T0, T1, uint32_t);
        !          1151:     T1 = 0;
        !          1152: }
        !          1153: 
        !          1154: NEON_OP(abdl_s64)
        !          1155: {
        !          1156:     DO_ABD(T0, T0, T1, int32_t);
        !          1157:     T1 = 0;
        !          1158: }
        !          1159: #undef DO_ABD
        !          1160: 
        !          1161: /* Widening multiple. Named type is the source type.  */
        !          1162: #define DO_MULL(dest, x, y, type1, type2) do { \
        !          1163:     type1 tmp_x = x; \
        !          1164:     type1 tmp_y = y; \
        !          1165:     dest = (type2)((type2)tmp_x * (type2)tmp_y); \
        !          1166:     } while(0)
        !          1167: 
        !          1168: NEON_OP(mull_u8)
        !          1169: {
        !          1170:     uint32_t tmp;
        !          1171:     uint32_t low;
        !          1172:     uint32_t high;
        !          1173: 
        !          1174:     DO_MULL(low, T0, T1, uint8_t, uint16_t);
        !          1175:     DO_MULL(tmp, T0 >> 8, T1 >> 8, uint8_t, uint16_t);
        !          1176:     low |= tmp << 16;
        !          1177:     DO_MULL(high, T0 >> 16, T1 >> 16, uint8_t, uint16_t);
        !          1178:     DO_MULL(tmp, T0 >> 24, T1 >> 24, uint8_t, uint16_t);
        !          1179:     high |= tmp << 16;
        !          1180:     T0 = low;
        !          1181:     T1 = high;
        !          1182:     FORCE_RET();
        !          1183: }
        !          1184: 
        !          1185: NEON_OP(mull_s8)
        !          1186: {
        !          1187:     uint32_t tmp;
        !          1188:     uint32_t low;
        !          1189:     uint32_t high;
        !          1190: 
        !          1191:     DO_MULL(low, T0, T1, int8_t, uint16_t);
        !          1192:     DO_MULL(tmp, T0 >> 8, T1 >> 8, int8_t, uint16_t);
        !          1193:     low |= tmp << 16;
        !          1194:     DO_MULL(high, T0 >> 16, T1 >> 16, int8_t, uint16_t);
        !          1195:     DO_MULL(tmp, T0 >> 24, T1 >> 24, int8_t, uint16_t);
        !          1196:     high |= tmp << 16;
        !          1197:     T0 = low;
        !          1198:     T1 = high;
        !          1199:     FORCE_RET();
        !          1200: }
        !          1201: 
        !          1202: NEON_OP(mull_u16)
        !          1203: {
        !          1204:     uint32_t low;
        !          1205:     uint32_t high;
        !          1206: 
        !          1207:     DO_MULL(low, T0, T1, uint16_t, uint32_t);
        !          1208:     DO_MULL(high, T0 >> 16, T1 >> 16, uint16_t, uint32_t);
        !          1209:     T0 = low;
        !          1210:     T1 = high;
        !          1211:     FORCE_RET();
        !          1212: }
        !          1213: 
        !          1214: NEON_OP(mull_s16)
        !          1215: {
        !          1216:     uint32_t low;
        !          1217:     uint32_t high;
        !          1218: 
        !          1219:     DO_MULL(low, T0, T1, int16_t, uint32_t);
        !          1220:     DO_MULL(high, T0 >> 16, T1 >> 16, int16_t, uint32_t);
        !          1221:     T0 = low;
        !          1222:     T1 = high;
        !          1223:     FORCE_RET();
        !          1224: }
        !          1225: 
        !          1226: NEON_OP(addl_saturate_s32)
        !          1227: {
        !          1228:     uint32_t tmp;
        !          1229:     uint32_t res;
        !          1230: 
        !          1231:     tmp = env->vfp.scratch[0];
        !          1232:     res = T0 + tmp;
        !          1233:     if (((res ^ T0) & SIGNBIT) && !((T0 ^ tmp) & SIGNBIT)) {
        !          1234:         env->QF = 1;
        !          1235:         T0 = (T0 >> 31) ^ 0x7fffffff;
        !          1236:     } else {
        !          1237:       T0 = res;
        !          1238:     }
        !          1239:     tmp = env->vfp.scratch[1];
        !          1240:     res = T1 + tmp;
        !          1241:     if (((res ^ T1) & SIGNBIT) && !((T1 ^ tmp) & SIGNBIT)) {
        !          1242:         env->QF = 1;
        !          1243:         T1 = (T1 >> 31) ^ 0x7fffffff;
        !          1244:     } else {
        !          1245:       T1 = res;
        !          1246:     }
        !          1247:     FORCE_RET();
        !          1248: }
        !          1249: 
        !          1250: NEON_OP(addl_saturate_s64)
        !          1251: {
        !          1252:     uint64_t src1;
        !          1253:     uint64_t src2;
        !          1254:     uint64_t res;
        !          1255: 
        !          1256:     src1 = T0 + ((uint64_t)T1 << 32);
        !          1257:     src2 = env->vfp.scratch[0] + ((uint64_t)env->vfp.scratch[1] << 32);
        !          1258:     res = src1 + src2;
        !          1259:     if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) {
        !          1260:         env->QF = 1;
        !          1261:         T0 = ~(int64_t)src1 >> 63;
        !          1262:         T1 = T0 ^ 0x80000000;
        !          1263:     } else {
        !          1264:       T0 = res;
        !          1265:       T1 = res >> 32;
        !          1266:     }
        !          1267:     FORCE_RET();
        !          1268: }
        !          1269: 
        !          1270: NEON_OP(addl_saturate_u64)
        !          1271: {
        !          1272:     uint64_t src1;
        !          1273:     uint64_t src2;
        !          1274:     uint64_t res;
        !          1275: 
        !          1276:     src1 = T0 + ((uint64_t)T1 << 32);
        !          1277:     src2 = env->vfp.scratch[0] + ((uint64_t)env->vfp.scratch[1] << 32);
        !          1278:     res = src1 + src2;
        !          1279:     if (res < src1) {
        !          1280:         env->QF = 1;
        !          1281:         T0 = 0xffffffff;
        !          1282:         T1 = 0xffffffff;
        !          1283:     } else {
        !          1284:       T0 = res;
        !          1285:       T1 = res >> 32;
        !          1286:     }
        !          1287:     FORCE_RET();
        !          1288: }
        !          1289: 
        !          1290: NEON_OP(subl_saturate_s64)
        !          1291: {
        !          1292:     uint64_t src1;
        !          1293:     uint64_t src2;
        !          1294:     uint64_t res;
        !          1295: 
        !          1296:     src1 = T0 + ((uint64_t)T1 << 32);
        !          1297:     src2 = env->vfp.scratch[0] + ((uint64_t)env->vfp.scratch[1] << 32);
        !          1298:     res = src1 - src2;
        !          1299:     if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) {
        !          1300:         env->QF = 1;
        !          1301:         T0 = ~(int64_t)src1 >> 63;
        !          1302:         T1 = T0 ^ 0x80000000;
        !          1303:     } else {
        !          1304:       T0 = res;
        !          1305:       T1 = res >> 32;
        !          1306:     }
        !          1307:     FORCE_RET();
        !          1308: }
        !          1309: 
        !          1310: NEON_OP(subl_saturate_u64)
        !          1311: {
        !          1312:     uint64_t src1;
        !          1313:     uint64_t src2;
        !          1314:     uint64_t res;
        !          1315: 
        !          1316:     src1 = T0 + ((uint64_t)T1 << 32);
        !          1317:     src2 = env->vfp.scratch[0] + ((uint64_t)env->vfp.scratch[1] << 32);
        !          1318:     if (src1 < src2) {
        !          1319:         env->QF = 1;
        !          1320:         T0 = 0;
        !          1321:         T1 = 0;
        !          1322:     } else {
        !          1323:       res = src1 - src2;
        !          1324:       T0 = res;
        !          1325:       T1 = res >> 32;
        !          1326:     }
        !          1327:     FORCE_RET();
        !          1328: }
        !          1329: 
        !          1330: NEON_OP(negl_u16)
        !          1331: {
        !          1332:     uint32_t tmp;
        !          1333:     tmp = T0 >> 16;
        !          1334:     tmp = -tmp;
        !          1335:     T0 = (-T0 & 0xffff) | (tmp << 16);
        !          1336:     tmp = T1 >> 16;
        !          1337:     tmp = -tmp;
        !          1338:     T1 = (-T1 & 0xffff) | (tmp << 16);
        !          1339:     FORCE_RET();
        !          1340: }
        !          1341: 
        !          1342: NEON_OP(negl_u32)
        !          1343: {
        !          1344:     T0 = -T0;
        !          1345:     T1 = -T1;
        !          1346:     FORCE_RET();
        !          1347: }
        !          1348: 
        !          1349: NEON_OP(negl_u64)
        !          1350: {
        !          1351:     uint64_t val;
        !          1352: 
        !          1353:     val = T0 | ((uint64_t)T1 << 32);
        !          1354:     val = -val;
        !          1355:     T0 = val;
        !          1356:     T1 = val >> 32;
        !          1357:     FORCE_RET();
        !          1358: }
        !          1359: 
        !          1360: /* Scalar operations.  */
        !          1361: NEON_OP(dup_low16)
        !          1362: {
        !          1363:     T0 = (T0 & 0xffff) | (T0 << 16);
        !          1364:     FORCE_RET();
        !          1365: }
        !          1366: 
        !          1367: NEON_OP(dup_high16)
        !          1368: {
        !          1369:     T0 = (T0 >> 16) | (T0 & 0xffff0000);
        !          1370:     FORCE_RET();
        !          1371: }
        !          1372: 
        !          1373: /* Helper for VEXT */
        !          1374: NEON_OP(extract)
        !          1375: {
        !          1376:     int shift = PARAM1;
        !          1377:     T0 = (T0 >> shift) | (T1 << (32 - shift));
        !          1378:     FORCE_RET();
        !          1379: }
        !          1380: 
        !          1381: /* Pairwise add long.  Named type is source type.  */
        !          1382: NEON_OP(paddl_s8)
        !          1383: {
        !          1384:     int8_t src1;
        !          1385:     int8_t src2;
        !          1386:     uint16_t result;
        !          1387:     src1 = T0 >> 24;
        !          1388:     src2 = T0 >> 16;
        !          1389:     result = (uint16_t)src1 + src2;
        !          1390:     src1 = T0 >> 8;
        !          1391:     src2 = T0;
        !          1392:     T0 = (uint16_t)((uint16_t)src1 + src2) | ((uint32_t)result << 16);
        !          1393:     FORCE_RET();
        !          1394: }
        !          1395: 
        !          1396: NEON_OP(paddl_u8)
        !          1397: {
        !          1398:     uint8_t src1;
        !          1399:     uint8_t src2;
        !          1400:     uint16_t result;
        !          1401:     src1 = T0 >> 24;
        !          1402:     src2 = T0 >> 16;
        !          1403:     result = (uint16_t)src1 + src2;
        !          1404:     src1 = T0 >> 8;
        !          1405:     src2 = T0;
        !          1406:     T0 = (uint16_t)((uint16_t)src1 + src2) | ((uint32_t)result << 16);
        !          1407:     FORCE_RET();
        !          1408: }
        !          1409: 
        !          1410: NEON_OP(paddl_s16)
        !          1411: {
        !          1412:     T0 = (uint32_t)(int16_t)T0 + (uint32_t)(int16_t)(T0 >> 16);
        !          1413:     FORCE_RET();
        !          1414: }
        !          1415: 
        !          1416: NEON_OP(paddl_u16)
        !          1417: {
        !          1418:     T0 = (uint32_t)(uint16_t)T0 + (uint32_t)(uint16_t)(T0 >> 16);
        !          1419:     FORCE_RET();
        !          1420: }
        !          1421: 
        !          1422: NEON_OP(paddl_s32)
        !          1423: {
        !          1424:     int64_t tmp;
        !          1425:     tmp = (int64_t)(int32_t)T0 + (int64_t)(int32_t)T1;
        !          1426:     T0 = tmp;
        !          1427:     T1 = tmp >> 32;
        !          1428:     FORCE_RET();
        !          1429: }
        !          1430: 
        !          1431: NEON_OP(paddl_u32)
        !          1432: {
        !          1433:     uint64_t tmp;
        !          1434:     tmp = (uint64_t)T0 + (uint64_t)T1;
        !          1435:     T0 = tmp;
        !          1436:     T1 = tmp >> 32;
        !          1437:     FORCE_RET();
        !          1438: }
        !          1439: 
        !          1440: /* Count Leading Sign/Zero Bits.  */
        !          1441: static inline int do_clz8(uint8_t x)
        !          1442: {
        !          1443:     int n;
        !          1444:     for (n = 8; x; n--)
        !          1445:         x >>= 1;
        !          1446:     return n;
        !          1447: }
        !          1448: 
        !          1449: static inline int do_clz16(uint16_t x)
        !          1450: {
        !          1451:     int n;
        !          1452:     for (n = 16; x; n--)
        !          1453:         x >>= 1;
        !          1454:     return n;
        !          1455: }
        !          1456: 
        !          1457: NEON_OP(clz_u8)
        !          1458: {
        !          1459:     uint32_t result;
        !          1460:     uint32_t tmp;
        !          1461: 
        !          1462:     tmp = T0;
        !          1463:     result = do_clz8(tmp);
        !          1464:     result |= do_clz8(tmp >> 8) << 8;
        !          1465:     result |= do_clz8(tmp >> 16) << 16;
        !          1466:     result |= do_clz8(tmp >> 24) << 24;
        !          1467:     T0 = result;
        !          1468:     FORCE_RET();
        !          1469: }
        !          1470: 
        !          1471: NEON_OP(clz_u16)
        !          1472: {
        !          1473:     uint32_t result;
        !          1474:     uint32_t tmp;
        !          1475:     tmp = T0;
        !          1476:     result = do_clz16(tmp);
        !          1477:     result |= do_clz16(tmp >> 16) << 16;
        !          1478:     T0 = result;
        !          1479:     FORCE_RET();
        !          1480: }
        !          1481: 
        !          1482: NEON_OP(cls_s8)
        !          1483: {
        !          1484:     uint32_t result;
        !          1485:     int8_t tmp;
        !          1486:     tmp = T0;
        !          1487:     result = do_clz8((tmp < 0) ? ~tmp : tmp) - 1;
        !          1488:     tmp = T0 >> 8;
        !          1489:     result |= (do_clz8((tmp < 0) ? ~tmp : tmp) - 1) << 8;
        !          1490:     tmp = T0 >> 16;
        !          1491:     result |= (do_clz8((tmp < 0) ? ~tmp : tmp) - 1) << 16;
        !          1492:     tmp = T0 >> 24;
        !          1493:     result |= (do_clz8((tmp < 0) ? ~tmp : tmp) - 1) << 24;
        !          1494:     T0 = result;
        !          1495:     FORCE_RET();
        !          1496: }
        !          1497: 
        !          1498: NEON_OP(cls_s16)
        !          1499: {
        !          1500:     uint32_t result;
        !          1501:     int16_t tmp;
        !          1502:     tmp = T0;
        !          1503:     result = do_clz16((tmp < 0) ? ~tmp : tmp) - 1;
        !          1504:     tmp = T0 >> 16;
        !          1505:     result |= (do_clz16((tmp < 0) ? ~tmp : tmp) - 1) << 16;
        !          1506:     T0 = result;
        !          1507:     FORCE_RET();
        !          1508: }
        !          1509: 
        !          1510: NEON_OP(cls_s32)
        !          1511: {
        !          1512:     int count;
        !          1513:     if ((int32_t)T0 < 0)
        !          1514:         T0 = ~T0;
        !          1515:     for (count = 32; T0 > 0; count--)
        !          1516:         T0 = T0 >> 1;
        !          1517:     T0 = count - 1;
        !          1518:     FORCE_RET();
        !          1519: }
        !          1520: 
        !          1521: /* Bit count.  */
        !          1522: NEON_OP(cnt_u8)
        !          1523: {
        !          1524:     T0 = (T0 & 0x55555555) + ((T0 >>  1) & 0x55555555);
        !          1525:     T0 = (T0 & 0x33333333) + ((T0 >>  2) & 0x33333333);
        !          1526:     T0 = (T0 & 0x0f0f0f0f) + ((T0 >>  4) & 0x0f0f0f0f);
        !          1527:     FORCE_RET();
        !          1528: }
        !          1529: 
        !          1530: /* Saturnating negation.  */
        !          1531: /* ??? Make these use NEON_VOP1 */
        !          1532: #define DO_QABS8(x) do { \
        !          1533:     if (x == (int8_t)0x80) { \
        !          1534:         x = 0x7f; \
        !          1535:         env->QF = 1; \
        !          1536:     } else if (x < 0) { \
        !          1537:         x = -x; \
        !          1538:     }} while (0)
        !          1539: NEON_OP(qabs_s8)
        !          1540: {
        !          1541:     neon_s8 vec;
        !          1542:     NEON_UNPACK(neon_s8, vec, T0);
        !          1543:     DO_QABS8(vec.v1);
        !          1544:     DO_QABS8(vec.v2);
        !          1545:     DO_QABS8(vec.v3);
        !          1546:     DO_QABS8(vec.v4);
        !          1547:     NEON_PACK(neon_s8, T0, vec);
        !          1548:     FORCE_RET();
        !          1549: }
        !          1550: #undef DO_QABS8
        !          1551: 
        !          1552: #define DO_QNEG8(x) do { \
        !          1553:     if (x == (int8_t)0x80) { \
        !          1554:         x = 0x7f; \
        !          1555:         env->QF = 1; \
        !          1556:     } else { \
        !          1557:         x = -x; \
        !          1558:     }} while (0)
        !          1559: NEON_OP(qneg_s8)
        !          1560: {
        !          1561:     neon_s8 vec;
        !          1562:     NEON_UNPACK(neon_s8, vec, T0);
        !          1563:     DO_QNEG8(vec.v1);
        !          1564:     DO_QNEG8(vec.v2);
        !          1565:     DO_QNEG8(vec.v3);
        !          1566:     DO_QNEG8(vec.v4);
        !          1567:     NEON_PACK(neon_s8, T0, vec);
        !          1568:     FORCE_RET();
        !          1569: }
        !          1570: #undef DO_QNEG8
        !          1571: 
        !          1572: #define DO_QABS16(x) do { \
        !          1573:     if (x == (int16_t)0x8000) { \
        !          1574:         x = 0x7fff; \
        !          1575:         env->QF = 1; \
        !          1576:     } else if (x < 0) { \
        !          1577:         x = -x; \
        !          1578:     }} while (0)
        !          1579: NEON_OP(qabs_s16)
        !          1580: {
        !          1581:     neon_s16 vec;
        !          1582:     NEON_UNPACK(neon_s16, vec, T0);
        !          1583:     DO_QABS16(vec.v1);
        !          1584:     DO_QABS16(vec.v2);
        !          1585:     NEON_PACK(neon_s16, T0, vec);
        !          1586:     FORCE_RET();
        !          1587: }
        !          1588: #undef DO_QABS16
        !          1589: 
        !          1590: #define DO_QNEG16(x) do { \
        !          1591:     if (x == (int16_t)0x8000) { \
        !          1592:         x = 0x7fff; \
        !          1593:         env->QF = 1; \
        !          1594:     } else { \
        !          1595:         x = -x; \
        !          1596:     }} while (0)
        !          1597: NEON_OP(qneg_s16)
        !          1598: {
        !          1599:     neon_s16 vec;
        !          1600:     NEON_UNPACK(neon_s16, vec, T0);
        !          1601:     DO_QNEG16(vec.v1);
        !          1602:     DO_QNEG16(vec.v2);
        !          1603:     NEON_PACK(neon_s16, T0, vec);
        !          1604:     FORCE_RET();
        !          1605: }
        !          1606: #undef DO_QNEG16
        !          1607: 
        !          1608: NEON_OP(qabs_s32)
        !          1609: {
        !          1610:     if (T0 == 0x80000000) {
        !          1611:         T0 = 0x7fffffff;
        !          1612:         env->QF = 1;
        !          1613:     } else if ((int32_t)T0 < 0) {
        !          1614:         T0 = -T0;
        !          1615:     }
        !          1616:     FORCE_RET();
        !          1617: }
        !          1618: 
        !          1619: NEON_OP(qneg_s32)
        !          1620: {
        !          1621:     if (T0 == 0x80000000) {
        !          1622:         T0 = 0x7fffffff;
        !          1623:         env->QF = 1;
        !          1624:     } else {
        !          1625:         T0 = -T0;
        !          1626:     }
        !          1627:     FORCE_RET();
        !          1628: }
        !          1629: 
        !          1630: /* Unary opperations */
        !          1631: #define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
        !          1632: NEON_VOP1(abs_s8, neon_s8, 4)
        !          1633: NEON_VOP1(abs_s16, neon_s16, 2)
        !          1634: NEON_OP(abs_s32)
        !          1635: {
        !          1636:     if ((int32_t)T0 < 0)
        !          1637:         T0 = -T0;
        !          1638:     FORCE_RET();
        !          1639: }
        !          1640: #undef NEON_FN
        !          1641: 
        !          1642: /* Transpose.  Argument order is rather strange to avoid special casing
        !          1643:    the tranlation code.
        !          1644:    On input T0 = rm, T1 = rd.  On output T0 = rd, T1 = rm  */
        !          1645: NEON_OP(trn_u8)
        !          1646: {
        !          1647:     uint32_t rd;
        !          1648:     uint32_t rm;
        !          1649:     rd = ((T0 & 0x00ff00ff) << 8) | (T1 & 0x00ff00ff);
        !          1650:     rm = ((T1 & 0xff00ff00) >> 8) | (T0 & 0xff00ff00);
        !          1651:     T0 = rd;
        !          1652:     T1 = rm;
        !          1653:     FORCE_RET();
        !          1654: }
        !          1655: 
        !          1656: NEON_OP(trn_u16)
        !          1657: {
        !          1658:     uint32_t rd;
        !          1659:     uint32_t rm;
        !          1660:     rd = (T0 << 16) | (T1 & 0xffff);
        !          1661:     rm = (T1 >> 16) | (T0 & 0xffff0000);
        !          1662:     T0 = rd;
        !          1663:     T1 = rm;
        !          1664:     FORCE_RET();
        !          1665: }
        !          1666: 
        !          1667: /* Worker routines for zip and unzip.  */
        !          1668: NEON_OP(unzip_u8)
        !          1669: {
        !          1670:     uint32_t rd;
        !          1671:     uint32_t rm;
        !          1672:     rd = (T0 & 0xff) | ((T0 >> 8) & 0xff00)
        !          1673:          | ((T1 << 16) & 0xff0000) | ((T1 << 8) & 0xff000000);
        !          1674:     rm = ((T0 >> 8) & 0xff) | ((T0 >> 16) & 0xff00)
        !          1675:          | ((T1 << 8) & 0xff0000) | (T1 & 0xff000000);
        !          1676:     T0 = rd;
        !          1677:     T1 = rm;
        !          1678:     FORCE_RET();
        !          1679: }
        !          1680: 
        !          1681: NEON_OP(zip_u8)
        !          1682: {
        !          1683:     uint32_t rd;
        !          1684:     uint32_t rm;
        !          1685:     rd = (T0 & 0xff) | ((T1 << 8) & 0xff00)
        !          1686:          | ((T0 << 16) & 0xff0000) | ((T1 << 24) & 0xff000000);
        !          1687:     rm = ((T0 >> 16) & 0xff) | ((T1 >> 8) & 0xff00)
        !          1688:          | ((T0 >> 8) & 0xff0000) | (T1 & 0xff000000);
        !          1689:     T0 = rd;
        !          1690:     T1 = rm;
        !          1691:     FORCE_RET();
        !          1692: }
        !          1693: 
        !          1694: NEON_OP(zip_u16)
        !          1695: {
        !          1696:     uint32_t tmp;
        !          1697: 
        !          1698:     tmp = (T0 & 0xffff) | (T1 << 16);
        !          1699:     T1 = (T1 & 0xffff0000) | (T0 >> 16);
        !          1700:     T0 = tmp;
        !          1701:     FORCE_RET();
        !          1702: }
        !          1703: 
        !          1704: /* Reciprocal/root estimate.  */
        !          1705: NEON_OP(recpe_u32)
        !          1706: {
        !          1707:     T0 = helper_recpe_u32(T0);
        !          1708: }
        !          1709: 
        !          1710: NEON_OP(rsqrte_u32)
        !          1711: {
        !          1712:     T0 = helper_rsqrte_u32(T0);
        !          1713: }
        !          1714: 
        !          1715: NEON_OP(recpe_f32)
        !          1716: {
        !          1717:     FT0s = helper_recpe_f32(FT0s);
        !          1718: }
        !          1719: 
        !          1720: NEON_OP(rsqrte_f32)
        !          1721: {
        !          1722:     FT0s = helper_rsqrte_f32(FT0s);
        !          1723: }
        !          1724: 
        !          1725: /* Table lookup.  This accessed the register file directly.  */
        !          1726: NEON_OP(tbl)
        !          1727: {
        !          1728:     helper_neon_tbl(PARAM1, PARAM2);
        !          1729: }
        !          1730: 
        !          1731: NEON_OP(dup_u8)
        !          1732: {
        !          1733:     T0 = (T0 >> PARAM1) & 0xff;
        !          1734:     T0 |= T0 << 8;
        !          1735:     T0 |= T0 << 16;
        !          1736:     FORCE_RET();
        !          1737: }
        !          1738: 
        !          1739: /* Helpers for element load/store.  */
        !          1740: NEON_OP(insert_elt)
        !          1741: {
        !          1742:     int shift = PARAM1;
        !          1743:     uint32_t mask = PARAM2;
        !          1744:     T2 = (T2 & mask) | (T0 << shift);
        !          1745:     FORCE_RET();
        !          1746: }
        !          1747: 
        !          1748: NEON_OP(extract_elt)
        !          1749: {
        !          1750:     int shift = PARAM1;
        !          1751:     uint32_t mask = PARAM2;
        !          1752:     T0 = (T2 & mask) >> shift;
        !          1753:     FORCE_RET();
        !          1754: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.