Revision a35f3ec7 target-i386/ops_sse.h
b/target-i386/ops_sse.h | ||
---|---|---|
1 | 1 |
/* |
2 |
* MMX/SSE/SSE2/PNI support
|
|
2 |
* MMX/3DNow!/SSE/SSE2/SSE3/PNI support
|
|
3 | 3 |
* |
4 | 4 |
* Copyright (c) 2005 Fabrice Bellard |
5 | 5 |
* |
... | ... | |
409 | 409 |
#define FCMPEQ(a, b) (a) == (b) ? -1 : 0 |
410 | 410 |
|
411 | 411 |
#define FMULLW(a, b) (a) * (b) |
412 |
#define FMULHRW(a, b) ((int16_t)(a) * (int16_t)(b) + 0x8000) >> 16 |
|
412 | 413 |
#define FMULHUW(a, b) (a) * (b) >> 16 |
413 | 414 |
#define FMULHW(a, b) (int16_t)(a) * (int16_t)(b) >> 16 |
414 | 415 |
|
... | ... | |
455 | 456 |
SSE_OP_L(op_pcmpeql, FCMPEQ) |
456 | 457 |
|
457 | 458 |
SSE_OP_W(op_pmullw, FMULLW) |
459 |
#if SHIFT == 0 |
|
460 |
SSE_OP_W(op_pmulhrw, FMULHRW) |
|
461 |
#endif |
|
458 | 462 |
SSE_OP_W(op_pmulhuw, FMULHUW) |
459 | 463 |
SSE_OP_W(op_pmulhw, FMULHW) |
460 | 464 |
|
... | ... | |
1383 | 1387 |
UNPCK_OP(l, 0) |
1384 | 1388 |
UNPCK_OP(h, 1) |
1385 | 1389 |
|
1390 |
/* 3DNow! float ops */ |
|
1391 |
#if SHIFT == 0 |
|
1392 |
void OPPROTO op_pi2fd(void) |
|
1393 |
{ |
|
1394 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1395 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1396 |
d->MMX_S(0) = int32_to_float32(s->MMX_L(0), &env->mmx_status); |
|
1397 |
d->MMX_S(1) = int32_to_float32(s->MMX_L(1), &env->mmx_status); |
|
1398 |
} |
|
1399 |
|
|
1400 |
void OPPROTO op_pi2fw(void) |
|
1401 |
{ |
|
1402 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1403 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1404 |
d->MMX_S(0) = int32_to_float32((int16_t)s->MMX_W(0), &env->mmx_status); |
|
1405 |
d->MMX_S(1) = int32_to_float32((int16_t)s->MMX_W(2), &env->mmx_status); |
|
1406 |
} |
|
1407 |
|
|
1408 |
void OPPROTO op_pf2id(void) |
|
1409 |
{ |
|
1410 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1411 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1412 |
d->MMX_L(0) = float32_to_int32_round_to_zero(s->MMX_S(0), &env->mmx_status); |
|
1413 |
d->MMX_L(1) = float32_to_int32_round_to_zero(s->MMX_S(1), &env->mmx_status); |
|
1414 |
} |
|
1415 |
|
|
1416 |
void OPPROTO op_pf2iw(void) |
|
1417 |
{ |
|
1418 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1419 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1420 |
d->MMX_L(0) = satsw(float32_to_int32_round_to_zero(s->MMX_S(0), &env->mmx_status)); |
|
1421 |
d->MMX_L(1) = satsw(float32_to_int32_round_to_zero(s->MMX_S(1), &env->mmx_status)); |
|
1422 |
} |
|
1423 |
|
|
1424 |
void OPPROTO op_pfacc(void) |
|
1425 |
{ |
|
1426 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1427 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1428 |
MMXReg r; |
|
1429 |
r.MMX_S(0) = float32_add(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); |
|
1430 |
r.MMX_S(1) = float32_add(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); |
|
1431 |
*d = r; |
|
1432 |
} |
|
1433 |
|
|
1434 |
void OPPROTO op_pfadd(void) |
|
1435 |
{ |
|
1436 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1437 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1438 |
d->MMX_S(0) = float32_add(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); |
|
1439 |
d->MMX_S(1) = float32_add(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); |
|
1440 |
} |
|
1441 |
|
|
1442 |
void OPPROTO op_pfcmpeq(void) |
|
1443 |
{ |
|
1444 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1445 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1446 |
d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0; |
|
1447 |
d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0; |
|
1448 |
} |
|
1449 |
|
|
1450 |
void OPPROTO op_pfcmpge(void) |
|
1451 |
{ |
|
1452 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1453 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1454 |
d->MMX_L(0) = float32_le(s->MMX_S(0), d->MMX_S(0), &env->mmx_status) ? -1 : 0; |
|
1455 |
d->MMX_L(1) = float32_le(s->MMX_S(1), d->MMX_S(1), &env->mmx_status) ? -1 : 0; |
|
1456 |
} |
|
1457 |
|
|
1458 |
void OPPROTO op_pfcmpgt(void) |
|
1459 |
{ |
|
1460 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1461 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1462 |
d->MMX_L(0) = float32_lt(s->MMX_S(0), d->MMX_S(0), &env->mmx_status) ? -1 : 0; |
|
1463 |
d->MMX_L(1) = float32_lt(s->MMX_S(1), d->MMX_S(1), &env->mmx_status) ? -1 : 0; |
|
1464 |
} |
|
1465 |
|
|
1466 |
void OPPROTO op_pfmax(void) |
|
1467 |
{ |
|
1468 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1469 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1470 |
if (float32_lt(d->MMX_S(0), s->MMX_S(0), &env->mmx_status)) |
|
1471 |
d->MMX_S(0) = s->MMX_S(0); |
|
1472 |
if (float32_lt(d->MMX_S(1), s->MMX_S(1), &env->mmx_status)) |
|
1473 |
d->MMX_S(1) = s->MMX_S(1); |
|
1474 |
} |
|
1475 |
|
|
1476 |
void OPPROTO op_pfmin(void) |
|
1477 |
{ |
|
1478 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1479 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1480 |
if (float32_lt(s->MMX_S(0), d->MMX_S(0), &env->mmx_status)) |
|
1481 |
d->MMX_S(0) = s->MMX_S(0); |
|
1482 |
if (float32_lt(s->MMX_S(1), d->MMX_S(1), &env->mmx_status)) |
|
1483 |
d->MMX_S(1) = s->MMX_S(1); |
|
1484 |
} |
|
1485 |
|
|
1486 |
void OPPROTO op_pfmul(void) |
|
1487 |
{ |
|
1488 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1489 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1490 |
d->MMX_S(0) = float32_mul(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); |
|
1491 |
d->MMX_S(1) = float32_mul(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); |
|
1492 |
} |
|
1493 |
|
|
1494 |
void OPPROTO op_pfnacc(void) |
|
1495 |
{ |
|
1496 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1497 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1498 |
MMXReg r; |
|
1499 |
r.MMX_S(0) = float32_sub(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); |
|
1500 |
r.MMX_S(1) = float32_sub(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); |
|
1501 |
*d = r; |
|
1502 |
} |
|
1503 |
|
|
1504 |
void OPPROTO op_pfpnacc(void) |
|
1505 |
{ |
|
1506 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1507 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1508 |
MMXReg r; |
|
1509 |
r.MMX_S(0) = float32_sub(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); |
|
1510 |
r.MMX_S(1) = float32_add(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); |
|
1511 |
*d = r; |
|
1512 |
} |
|
1513 |
|
|
1514 |
void OPPROTO op_pfrcp(void) |
|
1515 |
{ |
|
1516 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1517 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1518 |
d->MMX_S(0) = approx_rcp(s->MMX_S(0)); |
|
1519 |
d->MMX_S(1) = d->MMX_S(0); |
|
1520 |
} |
|
1521 |
|
|
1522 |
void OPPROTO op_pfrsqrt(void) |
|
1523 |
{ |
|
1524 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1525 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1526 |
d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff; |
|
1527 |
d->MMX_S(1) = approx_rsqrt(d->MMX_S(1)); |
|
1528 |
d->MMX_L(1) |= s->MMX_L(0) & 0x80000000; |
|
1529 |
d->MMX_L(0) = d->MMX_L(1); |
|
1530 |
} |
|
1531 |
|
|
1532 |
void OPPROTO op_pfsub(void) |
|
1533 |
{ |
|
1534 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1535 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1536 |
d->MMX_S(0) = float32_sub(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); |
|
1537 |
d->MMX_S(1) = float32_sub(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); |
|
1538 |
} |
|
1539 |
|
|
1540 |
void OPPROTO op_pfsubr(void) |
|
1541 |
{ |
|
1542 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1543 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1544 |
d->MMX_S(0) = float32_sub(s->MMX_S(0), d->MMX_S(0), &env->mmx_status); |
|
1545 |
d->MMX_S(1) = float32_sub(s->MMX_S(1), d->MMX_S(1), &env->mmx_status); |
|
1546 |
} |
|
1547 |
|
|
1548 |
void OPPROTO op_pswapd(void) |
|
1549 |
{ |
|
1550 |
MMXReg *d = (MMXReg *)((char *)env + PARAM1); |
|
1551 |
MMXReg *s = (MMXReg *)((char *)env + PARAM2); |
|
1552 |
MMXReg r; |
|
1553 |
r.MMX_L(0) = s->MMX_L(1); |
|
1554 |
r.MMX_L(1) = s->MMX_L(0); |
|
1555 |
*d = r; |
|
1556 |
} |
|
1557 |
#endif |
|
1558 |
|
|
1386 | 1559 |
#undef SHIFT |
1387 | 1560 |
#undef XMM_ONLY |
1388 | 1561 |
#undef Reg |
Also available in: Unified diff