Home | History | Annotate | Download | only in target-i386
      1 /*
      2  *  MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI support
      3  *
      4  *  Copyright (c) 2005 Fabrice Bellard
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Lesser General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Lesser General Public
     17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18  */
     19 #if SHIFT == 0
     20 #define Reg MMXReg
     21 #define SUFFIX _mmx
     22 #else
     23 #define Reg XMMReg
     24 #define SUFFIX _xmm
     25 #endif
     26 
     27 #define dh_alias_Reg ptr
     28 #define dh_alias_XMMReg ptr
     29 #define dh_alias_MMXReg ptr
     30 #define dh_ctype_Reg Reg *
     31 #define dh_ctype_XMMReg XMMReg *
     32 #define dh_ctype_MMXReg MMXReg *
     33 #define dh_is_signed_Reg dh_is_signed_ptr
     34 #define dh_is_signed_XMMReg dh_is_signed_ptr
     35 #define dh_is_signed_MMXReg dh_is_signed_ptr
     36 
     37 DEF_HELPER_3(glue(psrlw, SUFFIX), void, env, Reg, Reg)
     38 DEF_HELPER_3(glue(psraw, SUFFIX), void, env, Reg, Reg)
     39 DEF_HELPER_3(glue(psllw, SUFFIX), void, env, Reg, Reg)
     40 DEF_HELPER_3(glue(psrld, SUFFIX), void, env, Reg, Reg)
     41 DEF_HELPER_3(glue(psrad, SUFFIX), void, env, Reg, Reg)
     42 DEF_HELPER_3(glue(pslld, SUFFIX), void, env, Reg, Reg)
     43 DEF_HELPER_3(glue(psrlq, SUFFIX), void, env, Reg, Reg)
     44 DEF_HELPER_3(glue(psllq, SUFFIX), void, env, Reg, Reg)
     45 
     46 #if SHIFT == 1
     47 DEF_HELPER_3(glue(psrldq, SUFFIX), void, env, Reg, Reg)
     48 DEF_HELPER_3(glue(pslldq, SUFFIX), void, env, Reg, Reg)
     49 #endif
     50 
     51 #define SSE_HELPER_B(name, F)\
     52     DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
     53 
     54 #define SSE_HELPER_W(name, F)\
     55     DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
     56 
     57 #define SSE_HELPER_L(name, F)\
     58     DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
     59 
     60 #define SSE_HELPER_Q(name, F)\
     61     DEF_HELPER_3(glue(name, SUFFIX), void, env, Reg, Reg)
     62 
     63 SSE_HELPER_B(paddb, FADD)
     64 SSE_HELPER_W(paddw, FADD)
     65 SSE_HELPER_L(paddl, FADD)
     66 SSE_HELPER_Q(paddq, FADD)
     67 
     68 SSE_HELPER_B(psubb, FSUB)
     69 SSE_HELPER_W(psubw, FSUB)
     70 SSE_HELPER_L(psubl, FSUB)
     71 SSE_HELPER_Q(psubq, FSUB)
     72 
     73 SSE_HELPER_B(paddusb, FADDUB)
     74 SSE_HELPER_B(paddsb, FADDSB)
     75 SSE_HELPER_B(psubusb, FSUBUB)
     76 SSE_HELPER_B(psubsb, FSUBSB)
     77 
     78 SSE_HELPER_W(paddusw, FADDUW)
     79 SSE_HELPER_W(paddsw, FADDSW)
     80 SSE_HELPER_W(psubusw, FSUBUW)
     81 SSE_HELPER_W(psubsw, FSUBSW)
     82 
     83 SSE_HELPER_B(pminub, FMINUB)
     84 SSE_HELPER_B(pmaxub, FMAXUB)
     85 
     86 SSE_HELPER_W(pminsw, FMINSW)
     87 SSE_HELPER_W(pmaxsw, FMAXSW)
     88 
     89 SSE_HELPER_Q(pand, FAND)
     90 SSE_HELPER_Q(pandn, FANDN)
     91 SSE_HELPER_Q(por, FOR)
     92 SSE_HELPER_Q(pxor, FXOR)
     93 
     94 SSE_HELPER_B(pcmpgtb, FCMPGTB)
     95 SSE_HELPER_W(pcmpgtw, FCMPGTW)
     96 SSE_HELPER_L(pcmpgtl, FCMPGTL)
     97 
     98 SSE_HELPER_B(pcmpeqb, FCMPEQ)
     99 SSE_HELPER_W(pcmpeqw, FCMPEQ)
    100 SSE_HELPER_L(pcmpeql, FCMPEQ)
    101 
    102 SSE_HELPER_W(pmullw, FMULLW)
    103 #if SHIFT == 0
    104 SSE_HELPER_W(pmulhrw, FMULHRW)
    105 #endif
    106 SSE_HELPER_W(pmulhuw, FMULHUW)
    107 SSE_HELPER_W(pmulhw, FMULHW)
    108 
    109 SSE_HELPER_B(pavgb, FAVG)
    110 SSE_HELPER_W(pavgw, FAVG)
    111 
    112 DEF_HELPER_3(glue(pmuludq, SUFFIX), void, env, Reg, Reg)
    113 DEF_HELPER_3(glue(pmaddwd, SUFFIX), void, env, Reg, Reg)
    114 
    115 DEF_HELPER_3(glue(psadbw, SUFFIX), void, env, Reg, Reg)
    116 DEF_HELPER_4(glue(maskmov, SUFFIX), void, env, Reg, Reg, tl)
    117 DEF_HELPER_2(glue(movl_mm_T0, SUFFIX), void, Reg, i32)
    118 #ifdef TARGET_X86_64
    119 DEF_HELPER_2(glue(movq_mm_T0, SUFFIX), void, Reg, i64)
    120 #endif
    121 
    122 #if SHIFT == 0
    123 DEF_HELPER_3(glue(pshufw, SUFFIX), void, Reg, Reg, int)
    124 #else
    125 DEF_HELPER_3(shufps, void, Reg, Reg, int)
    126 DEF_HELPER_3(shufpd, void, Reg, Reg, int)
    127 DEF_HELPER_3(glue(pshufd, SUFFIX), void, Reg, Reg, int)
    128 DEF_HELPER_3(glue(pshuflw, SUFFIX), void, Reg, Reg, int)
    129 DEF_HELPER_3(glue(pshufhw, SUFFIX), void, Reg, Reg, int)
    130 #endif
    131 
    132 #if SHIFT == 1
    133 /* FPU ops */
    134 /* XXX: not accurate */
    135 
    136 #define SSE_HELPER_S(name, F)                            \
    137     DEF_HELPER_3(name ## ps, void, env, Reg, Reg)        \
    138     DEF_HELPER_3(name ## ss, void, env, Reg, Reg)        \
    139     DEF_HELPER_3(name ## pd, void, env, Reg, Reg)        \
    140     DEF_HELPER_3(name ## sd, void, env, Reg, Reg)
    141 
    142 SSE_HELPER_S(add, FPU_ADD)
    143 SSE_HELPER_S(sub, FPU_SUB)
    144 SSE_HELPER_S(mul, FPU_MUL)
    145 SSE_HELPER_S(div, FPU_DIV)
    146 SSE_HELPER_S(min, FPU_MIN)
    147 SSE_HELPER_S(max, FPU_MAX)
    148 SSE_HELPER_S(sqrt, FPU_SQRT)
    149 
    150 
    151 DEF_HELPER_3(cvtps2pd, void, env, Reg, Reg)
    152 DEF_HELPER_3(cvtpd2ps, void, env, Reg, Reg)
    153 DEF_HELPER_3(cvtss2sd, void, env, Reg, Reg)
    154 DEF_HELPER_3(cvtsd2ss, void, env, Reg, Reg)
    155 DEF_HELPER_3(cvtdq2ps, void, env, Reg, Reg)
    156 DEF_HELPER_3(cvtdq2pd, void, env, Reg, Reg)
    157 DEF_HELPER_3(cvtpi2ps, void, env, XMMReg, MMXReg)
    158 DEF_HELPER_3(cvtpi2pd, void, env, XMMReg, MMXReg)
    159 DEF_HELPER_3(cvtsi2ss, void, env, XMMReg, i32)
    160 DEF_HELPER_3(cvtsi2sd, void, env, XMMReg, i32)
    161 
    162 #ifdef TARGET_X86_64
    163 DEF_HELPER_3(cvtsq2ss, void, env, XMMReg, i64)
    164 DEF_HELPER_3(cvtsq2sd, void, env, XMMReg, i64)
    165 #endif
    166 
    167 DEF_HELPER_3(cvtps2dq, void, env, XMMReg, XMMReg)
    168 DEF_HELPER_3(cvtpd2dq, void, env, XMMReg, XMMReg)
    169 DEF_HELPER_3(cvtps2pi, void, env, MMXReg, XMMReg)
    170 DEF_HELPER_3(cvtpd2pi, void, env, MMXReg, XMMReg)
    171 DEF_HELPER_2(cvtss2si, s32, env, XMMReg)
    172 DEF_HELPER_2(cvtsd2si, s32, env, XMMReg)
    173 #ifdef TARGET_X86_64
    174 DEF_HELPER_2(cvtss2sq, s64, env, XMMReg)
    175 DEF_HELPER_2(cvtsd2sq, s64, env, XMMReg)
    176 #endif
    177 
    178 DEF_HELPER_3(cvttps2dq, void, env, XMMReg, XMMReg)
    179 DEF_HELPER_3(cvttpd2dq, void, env, XMMReg, XMMReg)
    180 DEF_HELPER_3(cvttps2pi, void, env, MMXReg, XMMReg)
    181 DEF_HELPER_3(cvttpd2pi, void, env, MMXReg, XMMReg)
    182 DEF_HELPER_2(cvttss2si, s32, env, XMMReg)
    183 DEF_HELPER_2(cvttsd2si, s32, env, XMMReg)
    184 #ifdef TARGET_X86_64
    185 DEF_HELPER_2(cvttss2sq, s64, env, XMMReg)
    186 DEF_HELPER_2(cvttsd2sq, s64, env, XMMReg)
    187 #endif
    188 
    189 DEF_HELPER_3(rsqrtps, void, env, XMMReg, XMMReg)
    190 DEF_HELPER_3(rsqrtss, void, env, XMMReg, XMMReg)
    191 DEF_HELPER_3(rcpps, void, env, XMMReg, XMMReg)
    192 DEF_HELPER_3(rcpss, void, env, XMMReg, XMMReg)
    193 DEF_HELPER_3(extrq_r, void, env, XMMReg, XMMReg)
    194 DEF_HELPER_4(extrq_i, void, env, XMMReg, int, int)
    195 DEF_HELPER_3(insertq_r, void, env, XMMReg, XMMReg)
    196 DEF_HELPER_4(insertq_i, void, env, XMMReg, int, int)
    197 DEF_HELPER_3(haddps, void, env, XMMReg, XMMReg)
    198 DEF_HELPER_3(haddpd, void, env, XMMReg, XMMReg)
    199 DEF_HELPER_3(hsubps, void, env, XMMReg, XMMReg)
    200 DEF_HELPER_3(hsubpd, void, env, XMMReg, XMMReg)
    201 DEF_HELPER_3(addsubps, void, env, XMMReg, XMMReg)
    202 DEF_HELPER_3(addsubpd, void, env, XMMReg, XMMReg)
    203 
    204 #define SSE_HELPER_CMP(name, F)                           \
    205     DEF_HELPER_3(name ## ps, void, env, Reg, Reg)         \
    206     DEF_HELPER_3(name ## ss, void, env, Reg, Reg)         \
    207     DEF_HELPER_3(name ## pd, void, env, Reg, Reg)         \
    208     DEF_HELPER_3(name ## sd, void, env, Reg, Reg)
    209 
    210 SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
    211 SSE_HELPER_CMP(cmplt, FPU_CMPLT)
    212 SSE_HELPER_CMP(cmple, FPU_CMPLE)
    213 SSE_HELPER_CMP(cmpunord, FPU_CMPUNORD)
    214 SSE_HELPER_CMP(cmpneq, FPU_CMPNEQ)
    215 SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT)
    216 SSE_HELPER_CMP(cmpnle, FPU_CMPNLE)
    217 SSE_HELPER_CMP(cmpord, FPU_CMPORD)
    218 
    219 DEF_HELPER_3(ucomiss, void, env, Reg, Reg)
    220 DEF_HELPER_3(comiss, void, env, Reg, Reg)
    221 DEF_HELPER_3(ucomisd, void, env, Reg, Reg)
    222 DEF_HELPER_3(comisd, void, env, Reg, Reg)
    223 DEF_HELPER_2(movmskps, i32, env, Reg)
    224 DEF_HELPER_2(movmskpd, i32, env, Reg)
    225 #endif
    226 
    227 DEF_HELPER_2(glue(pmovmskb, SUFFIX), i32, env, Reg)
    228 DEF_HELPER_3(glue(packsswb, SUFFIX), void, env, Reg, Reg)
    229 DEF_HELPER_3(glue(packuswb, SUFFIX), void, env, Reg, Reg)
    230 DEF_HELPER_3(glue(packssdw, SUFFIX), void, env, Reg, Reg)
    231 #define UNPCK_OP(base_name, base)                                       \
    232     DEF_HELPER_3(glue(punpck ## base_name ## bw, SUFFIX), void, env, Reg, Reg) \
    233     DEF_HELPER_3(glue(punpck ## base_name ## wd, SUFFIX), void, env, Reg, Reg) \
    234     DEF_HELPER_3(glue(punpck ## base_name ## dq, SUFFIX), void, env, Reg, Reg)
    235 
    236 UNPCK_OP(l, 0)
    237 UNPCK_OP(h, 1)
    238 
    239 #if SHIFT == 1
    240 DEF_HELPER_3(glue(punpcklqdq, SUFFIX), void, env, Reg, Reg)
    241 DEF_HELPER_3(glue(punpckhqdq, SUFFIX), void, env, Reg, Reg)
    242 #endif
    243 
    244 /* 3DNow! float ops */
    245 #if SHIFT == 0
    246 DEF_HELPER_3(pi2fd, void, env, MMXReg, MMXReg)
    247 DEF_HELPER_3(pi2fw, void, env, MMXReg, MMXReg)
    248 DEF_HELPER_3(pf2id, void, env, MMXReg, MMXReg)
    249 DEF_HELPER_3(pf2iw, void, env, MMXReg, MMXReg)
    250 DEF_HELPER_3(pfacc, void, env, MMXReg, MMXReg)
    251 DEF_HELPER_3(pfadd, void, env, MMXReg, MMXReg)
    252 DEF_HELPER_3(pfcmpeq, void, env, MMXReg, MMXReg)
    253 DEF_HELPER_3(pfcmpge, void, env, MMXReg, MMXReg)
    254 DEF_HELPER_3(pfcmpgt, void, env, MMXReg, MMXReg)
    255 DEF_HELPER_3(pfmax, void, env, MMXReg, MMXReg)
    256 DEF_HELPER_3(pfmin, void, env, MMXReg, MMXReg)
    257 DEF_HELPER_3(pfmul, void, env, MMXReg, MMXReg)
    258 DEF_HELPER_3(pfnacc, void, env, MMXReg, MMXReg)
    259 DEF_HELPER_3(pfpnacc, void, env, MMXReg, MMXReg)
    260 DEF_HELPER_3(pfrcp, void, env, MMXReg, MMXReg)
    261 DEF_HELPER_3(pfrsqrt, void, env, MMXReg, MMXReg)
    262 DEF_HELPER_3(pfsub, void, env, MMXReg, MMXReg)
    263 DEF_HELPER_3(pfsubr, void, env, MMXReg, MMXReg)
    264 DEF_HELPER_3(pswapd, void, env, MMXReg, MMXReg)
    265 #endif
    266 
    267 /* SSSE3 op helpers */
    268 DEF_HELPER_3(glue(phaddw, SUFFIX), void, env, Reg, Reg)
    269 DEF_HELPER_3(glue(phaddd, SUFFIX), void, env, Reg, Reg)
    270 DEF_HELPER_3(glue(phaddsw, SUFFIX), void, env, Reg, Reg)
    271 DEF_HELPER_3(glue(phsubw, SUFFIX), void, env, Reg, Reg)
    272 DEF_HELPER_3(glue(phsubd, SUFFIX), void, env, Reg, Reg)
    273 DEF_HELPER_3(glue(phsubsw, SUFFIX), void, env, Reg, Reg)
    274 DEF_HELPER_3(glue(pabsb, SUFFIX), void, env, Reg, Reg)
    275 DEF_HELPER_3(glue(pabsw, SUFFIX), void, env, Reg, Reg)
    276 DEF_HELPER_3(glue(pabsd, SUFFIX), void, env, Reg, Reg)
    277 DEF_HELPER_3(glue(pmaddubsw, SUFFIX), void, env, Reg, Reg)
    278 DEF_HELPER_3(glue(pmulhrsw, SUFFIX), void, env, Reg, Reg)
    279 DEF_HELPER_3(glue(pshufb, SUFFIX), void, env, Reg, Reg)
    280 DEF_HELPER_3(glue(psignb, SUFFIX), void, env, Reg, Reg)
    281 DEF_HELPER_3(glue(psignw, SUFFIX), void, env, Reg, Reg)
    282 DEF_HELPER_3(glue(psignd, SUFFIX), void, env, Reg, Reg)
    283 DEF_HELPER_4(glue(palignr, SUFFIX), void, env, Reg, Reg, s32)
    284 
    285 /* SSE4.1 op helpers */
    286 #if SHIFT == 1
    287 DEF_HELPER_3(glue(pblendvb, SUFFIX), void, env, Reg, Reg)
    288 DEF_HELPER_3(glue(blendvps, SUFFIX), void, env, Reg, Reg)
    289 DEF_HELPER_3(glue(blendvpd, SUFFIX), void, env, Reg, Reg)
    290 DEF_HELPER_3(glue(ptest, SUFFIX), void, env, Reg, Reg)
    291 DEF_HELPER_3(glue(pmovsxbw, SUFFIX), void, env, Reg, Reg)
    292 DEF_HELPER_3(glue(pmovsxbd, SUFFIX), void, env, Reg, Reg)
    293 DEF_HELPER_3(glue(pmovsxbq, SUFFIX), void, env, Reg, Reg)
    294 DEF_HELPER_3(glue(pmovsxwd, SUFFIX), void, env, Reg, Reg)
    295 DEF_HELPER_3(glue(pmovsxwq, SUFFIX), void, env, Reg, Reg)
    296 DEF_HELPER_3(glue(pmovsxdq, SUFFIX), void, env, Reg, Reg)
    297 DEF_HELPER_3(glue(pmovzxbw, SUFFIX), void, env, Reg, Reg)
    298 DEF_HELPER_3(glue(pmovzxbd, SUFFIX), void, env, Reg, Reg)
    299 DEF_HELPER_3(glue(pmovzxbq, SUFFIX), void, env, Reg, Reg)
    300 DEF_HELPER_3(glue(pmovzxwd, SUFFIX), void, env, Reg, Reg)
    301 DEF_HELPER_3(glue(pmovzxwq, SUFFIX), void, env, Reg, Reg)
    302 DEF_HELPER_3(glue(pmovzxdq, SUFFIX), void, env, Reg, Reg)
    303 DEF_HELPER_3(glue(pmuldq, SUFFIX), void, env, Reg, Reg)
    304 DEF_HELPER_3(glue(pcmpeqq, SUFFIX), void, env, Reg, Reg)
    305 DEF_HELPER_3(glue(packusdw, SUFFIX), void, env, Reg, Reg)
    306 DEF_HELPER_3(glue(pminsb, SUFFIX), void, env, Reg, Reg)
    307 DEF_HELPER_3(glue(pminsd, SUFFIX), void, env, Reg, Reg)
    308 DEF_HELPER_3(glue(pminuw, SUFFIX), void, env, Reg, Reg)
    309 DEF_HELPER_3(glue(pminud, SUFFIX), void, env, Reg, Reg)
    310 DEF_HELPER_3(glue(pmaxsb, SUFFIX), void, env, Reg, Reg)
    311 DEF_HELPER_3(glue(pmaxsd, SUFFIX), void, env, Reg, Reg)
    312 DEF_HELPER_3(glue(pmaxuw, SUFFIX), void, env, Reg, Reg)
    313 DEF_HELPER_3(glue(pmaxud, SUFFIX), void, env, Reg, Reg)
    314 DEF_HELPER_3(glue(pmulld, SUFFIX), void, env, Reg, Reg)
    315 DEF_HELPER_3(glue(phminposuw, SUFFIX), void, env, Reg, Reg)
    316 DEF_HELPER_4(glue(roundps, SUFFIX), void, env, Reg, Reg, i32)
    317 DEF_HELPER_4(glue(roundpd, SUFFIX), void, env, Reg, Reg, i32)
    318 DEF_HELPER_4(glue(roundss, SUFFIX), void, env, Reg, Reg, i32)
    319 DEF_HELPER_4(glue(roundsd, SUFFIX), void, env, Reg, Reg, i32)
    320 DEF_HELPER_4(glue(blendps, SUFFIX), void, env, Reg, Reg, i32)
    321 DEF_HELPER_4(glue(blendpd, SUFFIX), void, env, Reg, Reg, i32)
    322 DEF_HELPER_4(glue(pblendw, SUFFIX), void, env, Reg, Reg, i32)
    323 DEF_HELPER_4(glue(dpps, SUFFIX), void, env, Reg, Reg, i32)
    324 DEF_HELPER_4(glue(dppd, SUFFIX), void, env, Reg, Reg, i32)
    325 DEF_HELPER_4(glue(mpsadbw, SUFFIX), void, env, Reg, Reg, i32)
    326 #endif
    327 
    328 /* SSE4.2 op helpers */
    329 #if SHIFT == 1
    330 DEF_HELPER_3(glue(pcmpgtq, SUFFIX), void, env, Reg, Reg)
    331 DEF_HELPER_4(glue(pcmpestri, SUFFIX), void, env, Reg, Reg, i32)
    332 DEF_HELPER_4(glue(pcmpestrm, SUFFIX), void, env, Reg, Reg, i32)
    333 DEF_HELPER_4(glue(pcmpistri, SUFFIX), void, env, Reg, Reg, i32)
    334 DEF_HELPER_4(glue(pcmpistrm, SUFFIX), void, env, Reg, Reg, i32)
    335 DEF_HELPER_3(crc32, tl, i32, tl, i32)
    336 DEF_HELPER_3(popcnt, tl, env, tl, i32)
    337 #endif
    338 
    339 /* AES-NI op helpers */
    340 #if SHIFT == 1
    341 DEF_HELPER_3(glue(aesdec, SUFFIX), void, env, Reg, Reg)
    342 DEF_HELPER_3(glue(aesdeclast, SUFFIX), void, env, Reg, Reg)
    343 DEF_HELPER_3(glue(aesenc, SUFFIX), void, env, Reg, Reg)
    344 DEF_HELPER_3(glue(aesenclast, SUFFIX), void, env, Reg, Reg)
    345 DEF_HELPER_3(glue(aesimc, SUFFIX), void, env, Reg, Reg)
    346 DEF_HELPER_4(glue(aeskeygenassist, SUFFIX), void, env, Reg, Reg, i32)
    347 DEF_HELPER_4(glue(pclmulqdq, SUFFIX), void, env, Reg, Reg, i32)
    348 #endif
    349 
    350 #undef SHIFT
    351 #undef Reg
    352 #undef SUFFIX
    353 
    354 #undef SSE_HELPER_B
    355 #undef SSE_HELPER_W
    356 #undef SSE_HELPER_L
    357 #undef SSE_HELPER_Q
    358 #undef SSE_HELPER_S
    359 #undef SSE_HELPER_CMP
    360 #undef UNPCK_OP
    361