| ... | ... | @@ -97,21 +97,20 @@ int main(int argc, char **argv) { |
| 97 | 97 | "#include <stdint.h>\n" |
| 98 | 98 | "#include <stdlib.h>\n" |
| 99 | 99 | "#include <string.h>\n" |
| 100 | "\n" |
| 101 | "static uint16_t i16_byteswap(uint16_t src) {\n" |
| 102 | " return (uint16_t)(uint8_t)(src >> 0) << 8 |\n" |
| 103 | " (uint16_t)(uint8_t)(src >> 8) << 0;\n" |
| 104 | "}\n" |
| 105 | "static uint32_t i32_byteswap(uint32_t src) {\n" |
| 106 | " return (uint32_t)i16_byteswap(src >> 0) << 16 |\n" |
| 107 | " (uint32_t)i16_byteswap(src >> 16) << 0;\n" |
| 108 | "}\n" |
| 109 | "static uint64_t i64_byteswap(uint64_t src) {\n" |
| 110 | " return (uint64_t)i32_byteswap(src >> 0) << 32 |\n" |
| 111 | " (uint64_t)i32_byteswap(src >> 32) << 0;\n" |
| 112 | "}\n" |
| 100 | 113 | "\n", out); |
| 101 | | if (is_big_endian) |
| 102 | | fputs("static uint16_t i16_byteswap(uint16_t src) {\n" |
| 103 | | " return (uint16_t)(uint8_t)(src >> 0) << 8 |\n" |
| 104 | | " (uint16_t)(uint8_t)(src >> 8) << 0;\n" |
| 105 | | "}\n" |
| 106 | | "static uint32_t i32_byteswap(uint32_t src) {\n" |
| 107 | | " return (uint32_t)i16_byteswap(src >> 0) << 16 |\n" |
| 108 | | " (uint32_t)i16_byteswap(src >> 16) << 0;\n" |
| 109 | | "}\n" |
| 110 | | "static uint64_t i64_byteswap(uint64_t src) {\n" |
| 111 | | " return (uint64_t)i32_byteswap(src >> 0) << 32 |\n" |
| 112 | | " (uint64_t)i32_byteswap(src >> 32) << 0;\n" |
| 113 | | "}\n" |
| 114 | | "\n", out); |
| 115 | 114 | fputs("static uint16_t load16_align0(const uint8_t *ptr) {\n" |
| 116 | 115 | " uint16_t val;\n" |
| 117 | 116 | " memcpy(&val, ptr, sizeof(val));\n", out); |
| ... | ... | @@ -165,6 +164,39 @@ int main(int argc, char **argv) { |
| 165 | 164 | " memcpy(&val, ptr, sizeof(val));\n", out); |
| 166 | 165 | if (is_big_endian) fputs(" val = i64_byteswap(val);", out); |
| 167 | 166 | fputs(" return val;\n" |
| 167 | "}\n" |
| 168 | "\n" |
| 169 | "static uint32_t i32_popcnt(uint32_t lhs) {\n" |
| 170 | " lhs = lhs - ((lhs >> 1) & UINT32_C(0x55555555));\n" |
| 171 | " lhs = (lhs & UINT32_C(0x33333333)) + ((lhs >> 2) & UINT32_C(0x33333333));\n" |
| 172 | " lhs = (lhs + (lhs >> 4)) & UINT32_C(0x0F0F0F0F);\n" |
| 173 | " return (lhs * UINT32_C(0x01010101)) >> 24;\n" |
| 174 | "}\n" |
| 175 | "static uint32_t i32_ctz(uint32_t lhs) {\n" |
| 176 | " return i32_popcnt(~lhs & (lhs - 1));\n" |
| 177 | "}\n" |
| 178 | "static uint32_t i32_clz(uint32_t lhs) {\n" |
| 179 | " lhs = i32_byteswap(lhs);\n" |
| 180 | " lhs = (lhs & UINT32_C(0x0F0F0F0F)) << 4 | (lhs & UINT32_C(0xF0F0F0F0)) >> 4;\n" |
| 181 | " lhs = (lhs & UINT32_C(0x33333333)) << 2 | (lhs & UINT32_C(0xCCCCCCCC)) >> 2;\n" |
| 182 | " lhs = (lhs & UINT32_C(0x55555555)) << 1 | (lhs & UINT32_C(0xAAAAAAAA)) >> 1;\n" |
| 183 | " return i32_ctz(lhs);\n" |
| 184 | "}\n" |
| 185 | "static uint64_t i64_popcnt(uint64_t lhs) {\n" |
| 186 | " lhs = lhs - ((lhs >> 1) & UINT64_C(0x5555555555555555));\n" |
| 187 | " lhs = (lhs & UINT64_C(0x3333333333333333)) + ((lhs >> 2) & UINT64_C(0x3333333333333333));\n" |
| 188 | " lhs = (lhs + (lhs >> 4)) & UINT64_C(0x0F0F0F0F0F0F0F0F);\n" |
| 189 | " return (lhs * UINT64_C(0x0101010101010101)) >> 56;\n" |
| 190 | "}\n" |
| 191 | "static uint64_t i64_ctz(uint64_t lhs) {\n" |
| 192 | " return i64_popcnt(~lhs & (lhs - 1));\n" |
| 193 | "}\n" |
| 194 | "static uint64_t i64_clz(uint64_t lhs) {\n" |
| 195 | " lhs = i64_byteswap(lhs);\n" |
| 196 | " lhs = (lhs & UINT64_C(0x0F0F0F0F0F0F0F0F)) << 4 | (lhs & UINT32_C(0xF0F0F0F0F0F0F0F0)) >> 4;\n" |
| 197 | " lhs = (lhs & UINT64_C(0x3333333333333333)) << 2 | (lhs & UINT32_C(0xCCCCCCCCCCCCCCCC)) >> 2;\n" |
| 198 | " lhs = (lhs & UINT64_C(0x5555555555555555)) << 1 | (lhs & UINT32_C(0xAAAAAAAAAAAAAAAA)) >> 1;\n" |
| 199 | " return i64_ctz(lhs);\n" |
| 168 | 200 | "}\n" |
| 169 | 201 | "\n" |
| 170 | 202 | "static void store16_align0(uint8_t *ptr, uint16_t val) {\n", out); |
| ... | ... | @@ -787,6 +819,7 @@ int main(int argc, char **argv) { |
| 787 | 819 | } else unreachable_depth -= 1; |
| 788 | 820 | switch (opcode) { |
| 789 | 821 | case WasmOpcode_else: |
| 822 | FuncGen_reuseReset(&fg); |
| 790 | 823 | FuncGen_outdent(&fg, out); |
| 791 | 824 | fputs("} else {\n", out); |
| 792 | 825 | break; |
| ... | ... | @@ -968,10 +1001,10 @@ int main(int argc, char **argv) { |
| 968 | 1001 | if (unreachable_depth == 0) { |
| 969 | 1002 | uint32_t cond = FuncGen_stackPop(&fg); |
| 970 | 1003 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 971 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 972 | | FuncGen_stackPush(&fg, out, FuncGen_localType(&fg, lhs)); |
| 973 | | fprintf(out, "l%" PRIu32 " ? l%" PRIu32 " : l%" PRIu32 ";\n", |
| 974 | | cond, lhs, rhs); |
| 1004 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1005 | FuncGen_indent(&fg, out); |
| 1006 | fprintf(out, "l%"PRIu32" = l%" PRIu32 " ? l%" PRIu32 " : l%" PRIu32 ";\n", |
| 1007 | lhs, cond, lhs, rhs); |
| 975 | 1008 | } |
| 976 | 1009 | break; |
| 977 | 1010 | |
| ... | ... | @@ -1369,89 +1402,55 @@ int main(int argc, char **argv) { |
| 1369 | 1402 | |
| 1370 | 1403 | case WasmOpcode_i32_eqz: |
| 1371 | 1404 | if (unreachable_depth == 0) { |
| 1372 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1373 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1374 | | fprintf(out, "!l%" PRIu32 ";\n", lhs); |
| 1405 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1406 | FuncGen_indent(&fg, out); |
| 1407 | fprintf(out, "l%" PRIu32 " = !l%" PRIu32 ";\n", lhs, lhs); |
| 1375 | 1408 | } |
| 1376 | 1409 | break; |
| 1377 | 1410 | case WasmOpcode_i32_eq: |
| 1378 | | if (unreachable_depth == 0) { |
| 1379 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1380 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1381 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1382 | | fprintf(out, "l%" PRIu32 " == l%" PRIu32 ";\n", lhs, rhs); |
| 1383 | | } |
| 1384 | | break; |
| 1385 | 1411 | case WasmOpcode_i32_ne: |
| 1386 | | if (unreachable_depth == 0) { |
| 1387 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1388 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1389 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1390 | | fprintf(out, "l%" PRIu32 " != l%" PRIu32 ";\n", lhs, rhs); |
| 1391 | | } |
| 1392 | | break; |
| 1393 | | case WasmOpcode_i32_lt_s: |
| 1394 | | if (unreachable_depth == 0) { |
| 1395 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1396 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1397 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1398 | | fprintf(out, "(int32_t)l%" PRIu32 " < (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1399 | | } |
| 1400 | | break; |
| 1401 | 1412 | case WasmOpcode_i32_lt_u: |
| 1402 | | if (unreachable_depth == 0) { |
| 1403 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1404 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1405 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1406 | | fprintf(out, "l%" PRIu32 " < l%" PRIu32 ";\n", lhs, rhs); |
| 1407 | | } |
| 1408 | | break; |
| 1409 | | case WasmOpcode_i32_gt_s: |
| 1410 | | if (unreachable_depth == 0) { |
| 1411 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1412 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1413 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1414 | | fprintf(out, "(int32_t)l%" PRIu32 " > (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1415 | | } |
| 1416 | | break; |
| 1417 | 1413 | case WasmOpcode_i32_gt_u: |
| 1418 | | if (unreachable_depth == 0) { |
| 1419 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1420 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1421 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1422 | | fprintf(out, "l%" PRIu32 " > l%" PRIu32 ";\n", lhs, rhs); |
| 1423 | | } |
| 1424 | | break; |
| 1425 | | case WasmOpcode_i32_le_s: |
| 1426 | | if (unreachable_depth == 0) { |
| 1427 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1428 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1429 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1430 | | fprintf(out, "(int32_t)l%" PRIu32 " <= (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1431 | | } |
| 1432 | | break; |
| 1433 | 1414 | case WasmOpcode_i32_le_u: |
| 1415 | case WasmOpcode_i32_ge_u: |
| 1416 | // i32 unsigned comparisons |
| 1434 | 1417 | if (unreachable_depth == 0) { |
| 1435 | 1418 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1436 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1437 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1438 | | fprintf(out, "l%" PRIu32 " <= l%" PRIu32 ";\n", lhs, rhs); |
| 1419 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1420 | const char *operator; |
| 1421 | switch (opcode) { |
| 1422 | case WasmOpcode_i32_eq: operator = "=="; break; |
| 1423 | case WasmOpcode_i32_ne: operator = "!="; break; |
| 1424 | case WasmOpcode_i32_lt_u: operator = "<"; break; |
| 1425 | case WasmOpcode_i32_gt_u: operator = ">"; break; |
| 1426 | case WasmOpcode_i32_le_u: operator = "<="; break; |
| 1427 | case WasmOpcode_i32_ge_u: operator = ">="; break; |
| 1428 | default: panic("unreachable"); |
| 1429 | } |
| 1430 | FuncGen_indent(&fg, out); |
| 1431 | fprintf(out, "l%" PRIu32 " = l%" PRIu32 " %s l%" PRIu32 ";\n", |
| 1432 | lhs, lhs, operator, rhs); |
| 1439 | 1433 | } |
| 1440 | 1434 | break; |
| 1435 | case WasmOpcode_i32_lt_s: |
| 1436 | case WasmOpcode_i32_gt_s: |
| 1437 | case WasmOpcode_i32_le_s: |
| 1441 | 1438 | case WasmOpcode_i32_ge_s: |
| 1439 | // i32 signed comparisons |
| 1442 | 1440 | if (unreachable_depth == 0) { |
| 1443 | 1441 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1444 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1445 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1446 | | fprintf(out, "(int32_t)l%" PRIu32 " >= (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1447 | | } |
| 1448 | | break; |
| 1449 | | case WasmOpcode_i32_ge_u: |
| 1450 | | if (unreachable_depth == 0) { |
| 1451 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1452 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1453 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1454 | | fprintf(out, "l%" PRIu32 " >= l%" PRIu32 ";\n", lhs, rhs); |
| 1442 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1443 | const char *operator; |
| 1444 | switch (opcode) { |
| 1445 | case WasmOpcode_i32_lt_s: operator = "<"; break; |
| 1446 | case WasmOpcode_i32_gt_s: operator = ">"; break; |
| 1447 | case WasmOpcode_i32_le_s: operator = "<="; break; |
| 1448 | case WasmOpcode_i32_ge_s: operator = ">="; break; |
| 1449 | default: panic("unreachable"); |
| 1450 | } |
| 1451 | FuncGen_indent(&fg, out); |
| 1452 | fprintf(out, "l%" PRIu32 " = (int32_t)l%" PRIu32 " %s (int32_t)l%" PRIu32 |
| 1453 | ";\n", lhs, lhs, operator, rhs); |
| 1455 | 1454 | } |
| 1456 | 1455 | break; |
| 1457 | 1456 | |
| ... | ... | @@ -1463,685 +1462,385 @@ int main(int argc, char **argv) { |
| 1463 | 1462 | } |
| 1464 | 1463 | break; |
| 1465 | 1464 | case WasmOpcode_i64_eq: |
| 1466 | | if (unreachable_depth == 0) { |
| 1467 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1468 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1469 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1470 | | fprintf(out, "l%" PRIu32 " == l%" PRIu32 ";\n", lhs, rhs); |
| 1471 | | } |
| 1472 | | break; |
| 1473 | 1465 | case WasmOpcode_i64_ne: |
| 1466 | case WasmOpcode_i64_lt_u: |
| 1467 | case WasmOpcode_i64_gt_u: |
| 1468 | case WasmOpcode_i64_le_u: |
| 1469 | case WasmOpcode_i64_ge_u: |
| 1470 | case WasmOpcode_f32_eq: |
| 1471 | case WasmOpcode_f32_ne: |
| 1472 | case WasmOpcode_f32_lt: |
| 1473 | case WasmOpcode_f32_gt: |
| 1474 | case WasmOpcode_f32_le: |
| 1475 | case WasmOpcode_f32_ge: |
| 1476 | case WasmOpcode_f64_eq: |
| 1477 | case WasmOpcode_f64_ne: |
| 1478 | case WasmOpcode_f64_lt: |
| 1479 | case WasmOpcode_f64_gt: |
| 1480 | case WasmOpcode_f64_le: |
| 1481 | case WasmOpcode_f64_ge: |
| 1482 | // non-i32 unsigned comparisons |
| 1474 | 1483 | if (unreachable_depth == 0) { |
| 1475 | 1484 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1476 | 1485 | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1486 | const char *operator; |
| 1487 | switch (opcode) { |
| 1488 | case WasmOpcode_i64_eq: |
| 1489 | case WasmOpcode_f32_eq: |
| 1490 | case WasmOpcode_f64_eq: |
| 1491 | operator = "=="; |
| 1492 | break; |
| 1493 | case WasmOpcode_i64_ne: |
| 1494 | case WasmOpcode_f32_ne: |
| 1495 | case WasmOpcode_f64_ne: |
| 1496 | operator = "!="; |
| 1497 | break; |
| 1498 | case WasmOpcode_i64_lt_u: |
| 1499 | case WasmOpcode_f32_lt: |
| 1500 | case WasmOpcode_f64_lt: |
| 1501 | operator = "<"; |
| 1502 | break; |
| 1503 | case WasmOpcode_i64_gt_u: |
| 1504 | case WasmOpcode_f32_gt: |
| 1505 | case WasmOpcode_f64_gt: |
| 1506 | operator = ">"; |
| 1507 | break; |
| 1508 | case WasmOpcode_i64_le_u: |
| 1509 | case WasmOpcode_f32_le: |
| 1510 | case WasmOpcode_f64_le: |
| 1511 | operator = "<="; |
| 1512 | break; |
| 1513 | case WasmOpcode_i64_ge_u: |
| 1514 | case WasmOpcode_f32_ge: |
| 1515 | case WasmOpcode_f64_ge: |
| 1516 | operator = ">="; |
| 1517 | break; |
| 1518 | default: panic("unreachable"); |
| 1519 | } |
| 1477 | 1520 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1478 | | fprintf(out, "l%" PRIu32 " != l%" PRIu32 ";\n", lhs, rhs); |
| 1521 | fprintf(out, "l%" PRIu32 " = l%" PRIu32 " %s l%" PRIu32 ";\n", |
| 1522 | lhs, lhs, operator, rhs); |
| 1479 | 1523 | } |
| 1480 | 1524 | break; |
| 1481 | 1525 | case WasmOpcode_i64_lt_s: |
| 1526 | case WasmOpcode_i64_gt_s: |
| 1527 | case WasmOpcode_i64_le_s: |
| 1528 | case WasmOpcode_i64_ge_s: |
| 1529 | // i64 signed comparisons |
| 1482 | 1530 | if (unreachable_depth == 0) { |
| 1483 | 1531 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1484 | 1532 | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1533 | const char *operator; |
| 1534 | switch (opcode) { |
| 1535 | case WasmOpcode_i64_lt_s: operator = "<"; break; |
| 1536 | case WasmOpcode_i64_gt_s: operator = ">"; break; |
| 1537 | case WasmOpcode_i64_le_s: operator = "<="; break; |
| 1538 | case WasmOpcode_i64_ge_s: operator = ">="; break; |
| 1539 | default: panic("unreachable"); |
| 1540 | } |
| 1485 | 1541 | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1486 | | fprintf(out, "(int64_t)l%" PRIu32 " < (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1542 | fprintf(out, "l%" PRIu32 " = (int64_t)l%" PRIu32 " %s (int64_t)l%" PRIu32 |
| 1543 | ";\n", lhs, lhs, operator, rhs); |
| 1487 | 1544 | } |
| 1488 | 1545 | break; |
| 1489 | | case WasmOpcode_i64_lt_u: |
| 1546 | |
| 1547 | case WasmOpcode_i32_clz: |
| 1548 | case WasmOpcode_i32_ctz: |
| 1549 | case WasmOpcode_i32_popcnt: |
| 1550 | case WasmOpcode_i64_clz: |
| 1551 | case WasmOpcode_i64_ctz: |
| 1552 | case WasmOpcode_i64_popcnt: |
| 1553 | case WasmOpcode_f32_abs: |
| 1554 | case WasmOpcode_f32_neg: |
| 1555 | case WasmOpcode_f32_ceil: |
| 1556 | case WasmOpcode_f32_floor: |
| 1557 | case WasmOpcode_f32_trunc: |
| 1558 | case WasmOpcode_f32_nearest: |
| 1559 | case WasmOpcode_f32_sqrt: |
| 1560 | case WasmOpcode_f64_abs: |
| 1561 | case WasmOpcode_f64_neg: |
| 1562 | case WasmOpcode_f64_ceil: |
| 1563 | case WasmOpcode_f64_floor: |
| 1564 | case WasmOpcode_f64_trunc: |
| 1565 | case WasmOpcode_f64_nearest: |
| 1566 | case WasmOpcode_f64_sqrt: |
| 1567 | // unary functions |
| 1490 | 1568 | if (unreachable_depth == 0) { |
| 1491 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1492 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1493 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1494 | | fprintf(out, "l%" PRIu32 " < l%" PRIu32 ";\n", lhs, rhs); |
| 1569 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1570 | const char *function; |
| 1571 | switch (opcode) { |
| 1572 | case WasmOpcode_i32_clz: function = "i32_clz"; break; |
| 1573 | case WasmOpcode_i32_ctz: function = "i32_ctz"; break; |
| 1574 | case WasmOpcode_i32_popcnt: function = "i32_popcnt"; break; |
| 1575 | case WasmOpcode_i64_clz: function = "i64_clz"; break; |
| 1576 | case WasmOpcode_i64_ctz: function = "i64_ctz"; break; |
| 1577 | case WasmOpcode_i64_popcnt: function = "i64_popcnt"; break; |
| 1578 | case WasmOpcode_f32_abs: function = "fabsf"; break; |
| 1579 | case WasmOpcode_f32_neg: |
| 1580 | case WasmOpcode_f64_neg: function = "-"; break; |
| 1581 | case WasmOpcode_f32_ceil: function = "ceilf"; break; |
| 1582 | case WasmOpcode_f32_floor: function = "floorf"; break; |
| 1583 | case WasmOpcode_f32_trunc: function = "truncf"; break; |
| 1584 | case WasmOpcode_f32_nearest: function = "roundf"; break; |
| 1585 | case WasmOpcode_f32_sqrt: function = "sqrtf"; break; |
| 1586 | case WasmOpcode_f64_abs: function = "fabs"; break; |
| 1587 | case WasmOpcode_f64_ceil: function = "ceil"; break; |
| 1588 | case WasmOpcode_f64_floor: function = "floor"; break; |
| 1589 | case WasmOpcode_f64_trunc: function = "trunc"; break; |
| 1590 | case WasmOpcode_f64_nearest: function = "round"; break; |
| 1591 | case WasmOpcode_f64_sqrt: function = "sqrt"; break; |
| 1592 | default: panic("unreachable"); |
| 1593 | } |
| 1594 | FuncGen_indent(&fg, out); |
| 1595 | fprintf(out, "l%" PRIu32 " = %s(l%" PRIu32 ");\n", lhs, function, lhs); |
| 1495 | 1596 | } |
| 1496 | 1597 | break; |
| 1497 | | case WasmOpcode_i64_gt_s: |
| 1598 | case WasmOpcode_i32_add: |
| 1599 | case WasmOpcode_i32_sub: |
| 1600 | case WasmOpcode_i32_mul: |
| 1601 | case WasmOpcode_i32_div_u: |
| 1602 | case WasmOpcode_i32_rem_u: |
| 1603 | case WasmOpcode_i32_and: |
| 1604 | case WasmOpcode_i32_or: |
| 1605 | case WasmOpcode_i32_xor: |
| 1606 | case WasmOpcode_i64_add: |
| 1607 | case WasmOpcode_i64_sub: |
| 1608 | case WasmOpcode_i64_mul: |
| 1609 | case WasmOpcode_i64_div_u: |
| 1610 | case WasmOpcode_i64_rem_u: |
| 1611 | case WasmOpcode_i64_and: |
| 1612 | case WasmOpcode_i64_or: |
| 1613 | case WasmOpcode_i64_xor: |
| 1614 | case WasmOpcode_f32_add: |
| 1615 | case WasmOpcode_f32_sub: |
| 1616 | case WasmOpcode_f32_mul: |
| 1617 | case WasmOpcode_f32_div: |
| 1618 | case WasmOpcode_f64_add: |
| 1619 | case WasmOpcode_f64_sub: |
| 1620 | case WasmOpcode_f64_mul: |
| 1621 | case WasmOpcode_f64_div: |
| 1622 | // unsigned binary operators |
| 1498 | 1623 | if (unreachable_depth == 0) { |
| 1499 | 1624 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1500 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1501 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1502 | | fprintf(out, "(int64_t)l%" PRIu32 " > (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1625 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1626 | char operator; |
| 1627 | switch (opcode) { |
| 1628 | case WasmOpcode_i32_add: |
| 1629 | case WasmOpcode_i64_add: |
| 1630 | case WasmOpcode_f32_add: |
| 1631 | case WasmOpcode_f64_add: |
| 1632 | operator = '+'; |
| 1633 | break; |
| 1634 | case WasmOpcode_i32_sub: |
| 1635 | case WasmOpcode_i64_sub: |
| 1636 | case WasmOpcode_f32_sub: |
| 1637 | case WasmOpcode_f64_sub: |
| 1638 | operator = '-'; |
| 1639 | break; |
| 1640 | case WasmOpcode_i32_mul: |
| 1641 | case WasmOpcode_i64_mul: |
| 1642 | case WasmOpcode_f32_mul: |
| 1643 | case WasmOpcode_f64_mul: |
| 1644 | operator = '*'; |
| 1645 | break; |
| 1646 | case WasmOpcode_i32_div_u: |
| 1647 | case WasmOpcode_i64_div_u: |
| 1648 | case WasmOpcode_f32_div: |
| 1649 | case WasmOpcode_f64_div: |
| 1650 | operator = '/'; |
| 1651 | break; |
| 1652 | case WasmOpcode_i32_rem_u: |
| 1653 | case WasmOpcode_i64_rem_u: |
| 1654 | operator = '%'; |
| 1655 | break; |
| 1656 | case WasmOpcode_i32_and: |
| 1657 | case WasmOpcode_i64_and: |
| 1658 | operator = '&'; |
| 1659 | break; |
| 1660 | case WasmOpcode_i32_or: |
| 1661 | case WasmOpcode_i64_or: |
| 1662 | operator = '|'; |
| 1663 | break; |
| 1664 | case WasmOpcode_i32_xor: |
| 1665 | case WasmOpcode_i64_xor: |
| 1666 | operator = '^'; |
| 1667 | break; |
| 1668 | default: panic("unreachable"); |
| 1669 | } |
| 1670 | FuncGen_indent(&fg, out); |
| 1671 | fprintf(out, "l%" PRIu32 " %c= l%" PRIu32 ";\n", lhs, operator, rhs); |
| 1503 | 1672 | } |
| 1504 | 1673 | break; |
| 1505 | | case WasmOpcode_i64_gt_u: |
| 1674 | case WasmOpcode_i32_div_s: |
| 1675 | case WasmOpcode_i32_rem_s: |
| 1676 | case WasmOpcode_i64_div_s: |
| 1677 | case WasmOpcode_i64_rem_s: |
| 1678 | // signed binary operators |
| 1506 | 1679 | if (unreachable_depth == 0) { |
| 1507 | 1680 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1508 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1509 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1510 | | fprintf(out, "l%" PRIu32 " > l%" PRIu32 ";\n", lhs, rhs); |
| 1681 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1682 | char operator; |
| 1683 | unsigned width; |
| 1684 | switch (opcode) { |
| 1685 | case WasmOpcode_i32_div_s: |
| 1686 | case WasmOpcode_i64_div_s: |
| 1687 | operator = '/'; |
| 1688 | break; |
| 1689 | case WasmOpcode_i32_rem_s: |
| 1690 | case WasmOpcode_i64_rem_s: |
| 1691 | operator = '%'; |
| 1692 | break; |
| 1693 | default: panic("unreachable"); |
| 1694 | } |
| 1695 | switch (opcode) { |
| 1696 | case WasmOpcode_i32_div_s: |
| 1697 | case WasmOpcode_i32_rem_s: |
| 1698 | width = 32; |
| 1699 | break; |
| 1700 | case WasmOpcode_i64_div_s: |
| 1701 | case WasmOpcode_i64_rem_s: |
| 1702 | width = 64; |
| 1703 | break; |
| 1704 | default: panic("unreachable"); |
| 1705 | } |
| 1706 | FuncGen_indent(&fg, out); |
| 1707 | fprintf(out, "l%" PRIu32 " = (uint%u_t)((int%u_t)l%" PRIu32 " %c " |
| 1708 | "(int%u_t)l%" PRIu32 ");\n", |
| 1709 | lhs, width, width, lhs, operator, width, rhs); |
| 1511 | 1710 | } |
| 1512 | 1711 | break; |
| 1513 | | case WasmOpcode_i64_le_s: |
| 1712 | case WasmOpcode_i32_shl: |
| 1713 | case WasmOpcode_i32_shr_u: |
| 1714 | case WasmOpcode_i64_shl: |
| 1715 | case WasmOpcode_i64_shr_u: |
| 1716 | // unsigned shift operators |
| 1514 | 1717 | if (unreachable_depth == 0) { |
| 1515 | 1718 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1516 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1517 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1518 | | fprintf(out, "(int64_t)l%" PRIu32 " <= (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1719 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1720 | char operator; |
| 1721 | unsigned width; |
| 1722 | switch (opcode) { |
| 1723 | case WasmOpcode_i32_shl: |
| 1724 | case WasmOpcode_i64_shl: |
| 1725 | operator = '<'; |
| 1726 | break; |
| 1727 | case WasmOpcode_i32_shr_u: |
| 1728 | case WasmOpcode_i64_shr_u: |
| 1729 | operator = '>'; |
| 1730 | break; |
| 1731 | default: panic("unreachable"); |
| 1732 | } |
| 1733 | switch (opcode) { |
| 1734 | case WasmOpcode_i32_shl: |
| 1735 | case WasmOpcode_i32_shr_u: |
| 1736 | width = 32; |
| 1737 | break; |
| 1738 | case WasmOpcode_i64_shl: |
| 1739 | case WasmOpcode_i64_shr_u: |
| 1740 | width = 64; |
| 1741 | break; |
| 1742 | default: panic("unreachable"); |
| 1743 | } |
| 1744 | FuncGen_indent(&fg, out); |
| 1745 | fprintf(out, "l%" PRIu32 " %c%c= l%" PRIu32 " & 0x%X;\n", |
| 1746 | lhs, operator, operator, rhs, width - 1); |
| 1519 | 1747 | } |
| 1520 | 1748 | break; |
| 1521 | | case WasmOpcode_i64_le_u: |
| 1749 | case WasmOpcode_i32_shr_s: |
| 1750 | case WasmOpcode_i64_shr_s: |
| 1751 | // signed shift operators |
| 1522 | 1752 | if (unreachable_depth == 0) { |
| 1523 | 1753 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1524 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1525 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1526 | | fprintf(out, "l%" PRIu32 " <= l%" PRIu32 ";\n", lhs, rhs); |
| 1754 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1755 | char operator; |
| 1756 | unsigned width; |
| 1757 | switch (opcode) { |
| 1758 | case WasmOpcode_i32_shr_s: |
| 1759 | case WasmOpcode_i64_shr_s: |
| 1760 | operator = '>'; |
| 1761 | break; |
| 1762 | default: panic("unreachable"); |
| 1763 | } |
| 1764 | switch (opcode) { |
| 1765 | case WasmOpcode_i32_shr_s: |
| 1766 | width = 32; |
| 1767 | break; |
| 1768 | case WasmOpcode_i64_shr_s: |
| 1769 | width = 64; |
| 1770 | break; |
| 1771 | default: panic("unreachable"); |
| 1772 | } |
| 1773 | FuncGen_indent(&fg, out); |
| 1774 | fprintf(out, "l%" PRIu32 " = (uint%u_t)((int%u_t)l%" PRIu32 " %c%c " |
| 1775 | "(l%" PRIu32 " & 0x%X));\n", |
| 1776 | lhs, width, width, lhs, operator, operator, rhs, width - 1); |
| 1527 | 1777 | } |
| 1528 | 1778 | break; |
| 1529 | | case WasmOpcode_i64_ge_s: |
| 1779 | case WasmOpcode_i32_rotl: |
| 1780 | case WasmOpcode_i32_rotr: |
| 1781 | case WasmOpcode_i64_rotl: |
| 1782 | case WasmOpcode_i64_rotr: |
| 1783 | // rotate operators |
| 1530 | 1784 | if (unreachable_depth == 0) { |
| 1531 | 1785 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1532 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1533 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1534 | | fprintf(out, "(int64_t)l%" PRIu32 " >= (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1786 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1787 | char forward_operator; |
| 1788 | char reverse_operator; |
| 1789 | unsigned width; |
| 1790 | switch (opcode) { |
| 1791 | case WasmOpcode_i32_rotl: |
| 1792 | case WasmOpcode_i64_rotl: |
| 1793 | forward_operator = '<'; |
| 1794 | reverse_operator = '>'; |
| 1795 | break; |
| 1796 | case WasmOpcode_i32_rotr: |
| 1797 | case WasmOpcode_i64_rotr: |
| 1798 | forward_operator = '>'; |
| 1799 | reverse_operator = '<'; |
| 1800 | break; |
| 1801 | default: panic("unreachable"); |
| 1802 | } |
| 1803 | switch (opcode) { |
| 1804 | case WasmOpcode_i32_rotl: |
| 1805 | case WasmOpcode_i32_rotr: |
| 1806 | width = 32; |
| 1807 | break; |
| 1808 | case WasmOpcode_i64_rotl: |
| 1809 | case WasmOpcode_i64_rotr: |
| 1810 | width = 64; |
| 1811 | break; |
| 1812 | default: panic("unreachable"); |
| 1813 | } |
| 1814 | FuncGen_indent(&fg, out); |
| 1815 | fprintf(out, "l%" PRIu32" = l%" PRIu32 " %c%c (l%" PRIu32 " & 0x%X) | " |
| 1816 | "l%" PRIu32 " %c%c (-l%" PRIu32" & 0x%X);\n", lhs, |
| 1817 | lhs, forward_operator, forward_operator, rhs, width - 1, |
| 1818 | lhs, reverse_operator, reverse_operator, rhs, width - 1); |
| 1535 | 1819 | } |
| 1536 | 1820 | break; |
| 1537 | | case WasmOpcode_i64_ge_u: |
| 1821 | case WasmOpcode_f32_min: |
| 1822 | case WasmOpcode_f32_max: |
| 1823 | case WasmOpcode_f32_copysign: |
| 1824 | case WasmOpcode_f64_min: |
| 1825 | case WasmOpcode_f64_max: |
| 1826 | case WasmOpcode_f64_copysign: |
| 1827 | // binary functions |
| 1538 | 1828 | if (unreachable_depth == 0) { |
| 1539 | 1829 | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1540 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1541 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1542 | | fprintf(out, "l%" PRIu32 " >= l%" PRIu32 ";\n", lhs, rhs); |
| 1543 | | } |
| 1544 | | break; |
| 1545 | | |
| 1546 | | case WasmOpcode_f32_eq: |
| 1547 | | if (unreachable_depth == 0) { |
| 1548 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1549 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1550 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1551 | | fprintf(out, "l%" PRIu32 " == l%" PRIu32 ";\n", lhs, rhs); |
| 1552 | | } |
| 1553 | | break; |
| 1554 | | case WasmOpcode_f32_ne: |
| 1555 | | if (unreachable_depth == 0) { |
| 1556 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1557 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1558 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1559 | | fprintf(out, "l%" PRIu32 " != l%" PRIu32 ";\n", lhs, rhs); |
| 1560 | | } |
| 1561 | | break; |
| 1562 | | case WasmOpcode_f32_lt: |
| 1563 | | if (unreachable_depth == 0) { |
| 1564 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1565 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1566 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1567 | | fprintf(out, "l%" PRIu32 " < l%" PRIu32 ";\n", lhs, rhs); |
| 1568 | | } |
| 1569 | | break; |
| 1570 | | case WasmOpcode_f32_gt: |
| 1571 | | if (unreachable_depth == 0) { |
| 1572 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1573 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1574 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1575 | | fprintf(out, "l%" PRIu32 " > l%" PRIu32 ";\n", lhs, rhs); |
| 1576 | | } |
| 1577 | | break; |
| 1578 | | case WasmOpcode_f32_le: |
| 1579 | | if (unreachable_depth == 0) { |
| 1580 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1581 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1582 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1583 | | fprintf(out, "l%" PRIu32 " <= l%" PRIu32 ";\n", lhs, rhs); |
| 1584 | | } |
| 1585 | | break; |
| 1586 | | case WasmOpcode_f32_ge: |
| 1587 | | if (unreachable_depth == 0) { |
| 1588 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1589 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1590 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1591 | | fprintf(out, "l%" PRIu32 " >= l%" PRIu32 ";\n", lhs, rhs); |
| 1592 | | } |
| 1593 | | break; |
| 1594 | | |
| 1595 | | case WasmOpcode_f64_eq: |
| 1596 | | if (unreachable_depth == 0) { |
| 1597 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1598 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1599 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1600 | | fprintf(out, "l%" PRIu32 " == l%" PRIu32 ";\n", lhs, rhs); |
| 1601 | | } |
| 1602 | | break; |
| 1603 | | case WasmOpcode_f64_ne: |
| 1604 | | if (unreachable_depth == 0) { |
| 1605 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1606 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1607 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1608 | | fprintf(out, "l%" PRIu32 " != l%" PRIu32 ";\n", lhs, rhs); |
| 1609 | | } |
| 1610 | | break; |
| 1611 | | case WasmOpcode_f64_lt: |
| 1612 | | if (unreachable_depth == 0) { |
| 1613 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1614 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1615 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1616 | | fprintf(out, "l%" PRIu32 " < l%" PRIu32 ";\n", lhs, rhs); |
| 1617 | | } |
| 1618 | | break; |
| 1619 | | case WasmOpcode_f64_gt: |
| 1620 | | if (unreachable_depth == 0) { |
| 1621 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1622 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1623 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1624 | | fprintf(out, "l%" PRIu32 " > l%" PRIu32 ";\n", lhs, rhs); |
| 1625 | | } |
| 1626 | | break; |
| 1627 | | case WasmOpcode_f64_le: |
| 1628 | | if (unreachable_depth == 0) { |
| 1629 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1630 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1631 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1632 | | fprintf(out, "l%" PRIu32 " <= l%" PRIu32 ";\n", lhs, rhs); |
| 1633 | | } |
| 1634 | | break; |
| 1635 | | case WasmOpcode_f64_ge: |
| 1636 | | if (unreachable_depth == 0) { |
| 1637 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1638 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1639 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1640 | | fprintf(out, "l%" PRIu32 " >= l%" PRIu32 ";\n", lhs, rhs); |
| 1641 | | } |
| 1642 | | break; |
| 1643 | | |
| 1644 | | case WasmOpcode_i32_clz: |
| 1645 | | if (unreachable_depth == 0) { |
| 1646 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1647 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1648 | | fprintf(out, "l%" PRIu32 " != 0 ? __builtin_clz(l%" PRIu32 ") : 32;\n", |
| 1649 | | lhs, lhs); |
| 1650 | | } |
| 1651 | | break; |
| 1652 | | case WasmOpcode_i32_ctz: |
| 1653 | | if (unreachable_depth == 0) { |
| 1654 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1655 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1656 | | fprintf(out, "l%" PRIu32 " != 0 ? __builtin_ctz(l%" PRIu32 ") : 32;\n", |
| 1657 | | lhs, lhs); |
| 1658 | | } |
| 1659 | | break; |
| 1660 | | case WasmOpcode_i32_popcnt: |
| 1661 | | if (unreachable_depth == 0) { |
| 1662 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1663 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1664 | | fprintf(out, "__builtin_popcount(l%" PRIu32 ");\n", lhs); |
| 1665 | | } |
| 1666 | | break; |
| 1667 | | case WasmOpcode_i32_add: |
| 1668 | | if (unreachable_depth == 0) { |
| 1669 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1670 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1671 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1672 | | fprintf(out, "l%" PRIu32 " + l%" PRIu32 ";\n", lhs, rhs); |
| 1673 | | } |
| 1674 | | break; |
| 1675 | | case WasmOpcode_i32_sub: |
| 1676 | | if (unreachable_depth == 0) { |
| 1677 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1678 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1679 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1680 | | fprintf(out, "l%" PRIu32 " - l%" PRIu32 ";\n", lhs, rhs); |
| 1681 | | } |
| 1682 | | break; |
| 1683 | | case WasmOpcode_i32_mul: |
| 1684 | | if (unreachable_depth == 0) { |
| 1685 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1686 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1687 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1688 | | fprintf(out, "l%" PRIu32 " * l%" PRIu32 ";\n", lhs, rhs); |
| 1689 | | } |
| 1690 | | break; |
| 1691 | | case WasmOpcode_i32_div_s: |
| 1692 | | if (unreachable_depth == 0) { |
| 1693 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1694 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1695 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1696 | | fprintf(out, "(int32_t)l%" PRIu32 " / (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1697 | | } |
| 1698 | | break; |
| 1699 | | case WasmOpcode_i32_div_u: |
| 1700 | | if (unreachable_depth == 0) { |
| 1701 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1702 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1703 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1704 | | fprintf(out, "l%" PRIu32 " / l%" PRIu32 ";\n", lhs, rhs); |
| 1705 | | } |
| 1706 | | break; |
| 1707 | | case WasmOpcode_i32_rem_s: |
| 1708 | | if (unreachable_depth == 0) { |
| 1709 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1710 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1711 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1712 | | fprintf(out, "(int32_t)l%" PRIu32 " %% (int32_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1713 | | } |
| 1714 | | break; |
| 1715 | | case WasmOpcode_i32_rem_u: |
| 1716 | | if (unreachable_depth == 0) { |
| 1717 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1718 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1719 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1720 | | fprintf(out, "l%" PRIu32 " %% l%" PRIu32 ";\n", lhs, rhs); |
| 1721 | | } |
| 1722 | | break; |
| 1723 | | case WasmOpcode_i32_and: |
| 1724 | | if (unreachable_depth == 0) { |
| 1725 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1726 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1727 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1728 | | fprintf(out, "l%" PRIu32 " & l%" PRIu32 ";\n", lhs, rhs); |
| 1729 | | } |
| 1730 | | break; |
| 1731 | | case WasmOpcode_i32_or: |
| 1732 | | if (unreachable_depth == 0) { |
| 1733 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1734 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1735 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1736 | | fprintf(out, "l%" PRIu32 " | l%" PRIu32 ";\n", lhs, rhs); |
| 1737 | | } |
| 1738 | | break; |
| 1739 | | case WasmOpcode_i32_xor: |
| 1740 | | if (unreachable_depth == 0) { |
| 1741 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1742 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1743 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1744 | | fprintf(out, "l%" PRIu32 " ^ l%" PRIu32 ";\n", lhs, rhs); |
| 1745 | | } |
| 1746 | | break; |
| 1747 | | case WasmOpcode_i32_shl: |
| 1748 | | if (unreachable_depth == 0) { |
| 1749 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1750 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1751 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1752 | | fprintf(out, "l%" PRIu32 " << (l%" PRIu32 " & 0x1F);\n", lhs, rhs); |
| 1753 | | } |
| 1754 | | break; |
| 1755 | | case WasmOpcode_i32_shr_s: |
| 1756 | | if (unreachable_depth == 0) { |
| 1757 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1758 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1759 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1760 | | fprintf(out, "(int32_t)l%" PRIu32 " >> (l%" PRIu32 " & 0x1F);\n", lhs, rhs); |
| 1761 | | } |
| 1762 | | break; |
| 1763 | | case WasmOpcode_i32_shr_u: |
| 1764 | | if (unreachable_depth == 0) { |
| 1765 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1766 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1767 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1768 | | fprintf(out, "l%" PRIu32 " >> (l%" PRIu32 " & 0x1F);\n", lhs, rhs); |
| 1769 | | } |
| 1770 | | break; |
| 1771 | | case WasmOpcode_i32_rotl: |
| 1772 | | if (unreachable_depth == 0) { |
| 1773 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1774 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1775 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1776 | | fprintf(out, "l%" PRIu32 " << (l%" PRIu32 " & 0x1F) | " |
| 1777 | | "l%" PRIu32 " >> (-l%" PRIu32" & 0x1F);\n", lhs, rhs, lhs, rhs); |
| 1778 | | } |
| 1779 | | break; |
| 1780 | | case WasmOpcode_i32_rotr: |
| 1781 | | if (unreachable_depth == 0) { |
| 1782 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1783 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1784 | | FuncGen_stackPush(&fg, out, WasmValType_i32); |
| 1785 | | fprintf(out, "l%" PRIu32 " >> (l%" PRIu32 " & 0x1F) | " |
| 1786 | | "l%" PRIu32 " << (-l%" PRIu32" & 0x1F);\n", lhs, rhs, lhs, rhs); |
| 1787 | | } |
| 1788 | | break; |
| 1789 | | |
| 1790 | | case WasmOpcode_i64_clz: |
| 1791 | | if (unreachable_depth == 0) { |
| 1792 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1793 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1794 | | fprintf(out, "l%" PRIu32 " != 0 ? __builtin_clzll(l%" PRIu32 ") : 64;\n", |
| 1795 | | lhs, lhs); |
| 1796 | | } |
| 1797 | | break; |
| 1798 | | case WasmOpcode_i64_ctz: |
| 1799 | | if (unreachable_depth == 0) { |
| 1800 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1801 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1802 | | fprintf(out, "l%" PRIu32 " != 0 ? __builtin_ctzll(l%" PRIu32 ") : 64;\n", |
| 1803 | | lhs, lhs); |
| 1804 | | } |
| 1805 | | break; |
| 1806 | | case WasmOpcode_i64_popcnt: |
| 1807 | | if (unreachable_depth == 0) { |
| 1808 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1809 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1810 | | fprintf(out, "__builtin_popcountll(l%" PRIu32 ");\n", lhs); |
| 1811 | | } |
| 1812 | | break; |
| 1813 | | case WasmOpcode_i64_add: |
| 1814 | | if (unreachable_depth == 0) { |
| 1815 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1816 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1817 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1818 | | fprintf(out, "l%" PRIu32 " + l%" PRIu32 ";\n", lhs, rhs); |
| 1819 | | } |
| 1820 | | break; |
| 1821 | | case WasmOpcode_i64_sub: |
| 1822 | | if (unreachable_depth == 0) { |
| 1823 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1824 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1825 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1826 | | fprintf(out, "l%" PRIu32 " - l%" PRIu32 ";\n", lhs, rhs); |
| 1827 | | } |
| 1828 | | break; |
| 1829 | | case WasmOpcode_i64_mul: |
| 1830 | | if (unreachable_depth == 0) { |
| 1831 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1832 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1833 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1834 | | fprintf(out, "l%" PRIu32 " * l%" PRIu32 ";\n", lhs, rhs); |
| 1835 | | } |
| 1836 | | break; |
| 1837 | | case WasmOpcode_i64_div_s: |
| 1838 | | if (unreachable_depth == 0) { |
| 1839 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1840 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1841 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1842 | | fprintf(out, "(int64_t)l%" PRIu32 " / (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1843 | | } |
| 1844 | | break; |
| 1845 | | case WasmOpcode_i64_div_u: |
| 1846 | | if (unreachable_depth == 0) { |
| 1847 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1848 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1849 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1850 | | fprintf(out, "l%" PRIu32 " / l%" PRIu32 ";\n", lhs, rhs); |
| 1851 | | } |
| 1852 | | break; |
| 1853 | | case WasmOpcode_i64_rem_s: |
| 1854 | | if (unreachable_depth == 0) { |
| 1855 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1856 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1857 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1858 | | fprintf(out, "(int64_t)l%" PRIu32 " %% (int64_t)l%" PRIu32 ";\n", lhs, rhs); |
| 1859 | | } |
| 1860 | | break; |
| 1861 | | case WasmOpcode_i64_rem_u: |
| 1862 | | if (unreachable_depth == 0) { |
| 1863 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1864 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1865 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1866 | | fprintf(out, "l%" PRIu32 " %% l%" PRIu32 ";\n", lhs, rhs); |
| 1867 | | } |
| 1868 | | break; |
| 1869 | | case WasmOpcode_i64_and: |
| 1870 | | if (unreachable_depth == 0) { |
| 1871 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1872 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1873 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1874 | | fprintf(out, "l%" PRIu32 " & l%" PRIu32 ";\n", lhs, rhs); |
| 1875 | | } |
| 1876 | | break; |
| 1877 | | case WasmOpcode_i64_or: |
| 1878 | | if (unreachable_depth == 0) { |
| 1879 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1880 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1881 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1882 | | fprintf(out, "l%" PRIu32 " | l%" PRIu32 ";\n", lhs, rhs); |
| 1883 | | } |
| 1884 | | break; |
| 1885 | | case WasmOpcode_i64_xor: |
| 1886 | | if (unreachable_depth == 0) { |
| 1887 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1888 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1889 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1890 | | fprintf(out, "l%" PRIu32 " ^ l%" PRIu32 ";\n", lhs, rhs); |
| 1891 | | } |
| 1892 | | break; |
| 1893 | | case WasmOpcode_i64_shl: |
| 1894 | | if (unreachable_depth == 0) { |
| 1895 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1896 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1897 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1898 | | fprintf(out, "l%" PRIu32 " << (l%" PRIu32 " & 0x3F);\n", lhs, rhs); |
| 1899 | | } |
| 1900 | | break; |
| 1901 | | case WasmOpcode_i64_shr_s: |
| 1902 | | if (unreachable_depth == 0) { |
| 1903 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1904 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1905 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1906 | | fprintf(out, "(int64_t)l%" PRIu32 " >> (l%" PRIu32 " & 0x3F);\n", lhs, rhs); |
| 1907 | | } |
| 1908 | | break; |
| 1909 | | case WasmOpcode_i64_shr_u: |
| 1910 | | if (unreachable_depth == 0) { |
| 1911 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1912 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1913 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1914 | | fprintf(out, "l%" PRIu32 " >> (l%" PRIu32 " & 0x3F);\n", lhs, rhs); |
| 1915 | | } |
| 1916 | | break; |
| 1917 | | case WasmOpcode_i64_rotl: |
| 1918 | | if (unreachable_depth == 0) { |
| 1919 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1920 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1921 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1922 | | fprintf(out, "l%" PRIu32 " << (l%" PRIu32 " & 0x3F) | " |
| 1923 | | "l%" PRIu32 " >> (-l%" PRIu32" & 0x3F);\n", lhs, rhs, lhs, rhs); |
| 1924 | | } |
| 1925 | | break; |
| 1926 | | case WasmOpcode_i64_rotr: |
| 1927 | | if (unreachable_depth == 0) { |
| 1928 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1929 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1930 | | FuncGen_stackPush(&fg, out, WasmValType_i64); |
| 1931 | | fprintf(out, "l%" PRIu32 " >> (l%" PRIu32 " & 0x3F) | " |
| 1932 | | "l%" PRIu32 " << (-l%" PRIu32" & 0x3F);\n", lhs, rhs, lhs, rhs); |
| 1933 | | } |
| 1934 | | break; |
| 1935 | | |
| 1936 | | case WasmOpcode_f32_abs: |
| 1937 | | if (unreachable_depth == 0) { |
| 1938 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1939 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1940 | | fprintf(out, "fabsf(l%" PRIu32 ");\n", lhs); |
| 1941 | | } |
| 1942 | | break; |
| 1943 | | case WasmOpcode_f32_neg: |
| 1944 | | if (unreachable_depth == 0) { |
| 1945 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1946 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1947 | | fprintf(out, "-l%" PRIu32 ";\n", lhs); |
| 1948 | | } |
| 1949 | | break; |
| 1950 | | case WasmOpcode_f32_ceil: |
| 1951 | | if (unreachable_depth == 0) { |
| 1952 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1953 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1954 | | fprintf(out, "ceilf(l%" PRIu32 ");\n", lhs); |
| 1955 | | } |
| 1956 | | break; |
| 1957 | | case WasmOpcode_f32_floor: |
| 1958 | | if (unreachable_depth == 0) { |
| 1959 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1960 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1961 | | fprintf(out, "floorf(l%" PRIu32 ");\n", lhs); |
| 1962 | | } |
| 1963 | | break; |
| 1964 | | case WasmOpcode_f32_trunc: |
| 1965 | | if (unreachable_depth == 0) { |
| 1966 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1967 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1968 | | fprintf(out, "truncf(l%" PRIu32 ");\n", lhs); |
| 1969 | | } |
| 1970 | | break; |
| 1971 | | case WasmOpcode_f32_nearest: |
| 1972 | | if (unreachable_depth == 0) { |
| 1973 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1974 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1975 | | fprintf(out, "roundf(l%" PRIu32 ");\n", lhs); |
| 1976 | | } |
| 1977 | | break; |
| 1978 | | case WasmOpcode_f32_sqrt: |
| 1979 | | if (unreachable_depth == 0) { |
| 1980 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1981 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1982 | | fprintf(out, "sqrtf(l%" PRIu32 ");\n", lhs); |
| 1983 | | } |
| 1984 | | break; |
| 1985 | | case WasmOpcode_f32_add: |
| 1986 | | if (unreachable_depth == 0) { |
| 1987 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1988 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1989 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1990 | | fprintf(out, "l%" PRIu32 " + l%" PRIu32 ";\n", lhs, rhs); |
| 1991 | | } |
| 1992 | | break; |
| 1993 | | case WasmOpcode_f32_sub: |
| 1994 | | if (unreachable_depth == 0) { |
| 1995 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 1996 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 1997 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 1998 | | fprintf(out, "l%" PRIu32 " - l%" PRIu32 ";\n", lhs, rhs); |
| 1999 | | } |
| 2000 | | break; |
| 2001 | | case WasmOpcode_f32_mul: |
| 2002 | | if (unreachable_depth == 0) { |
| 2003 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2004 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2005 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 2006 | | fprintf(out, "l%" PRIu32 " * l%" PRIu32 ";\n", lhs, rhs); |
| 2007 | | } |
| 2008 | | break; |
| 2009 | | case WasmOpcode_f32_div: |
| 2010 | | if (unreachable_depth == 0) { |
| 2011 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2012 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2013 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 2014 | | fprintf(out, "l%" PRIu32 " / l%" PRIu32 ";\n", lhs, rhs); |
| 2015 | | } |
| 2016 | | break; |
| 2017 | | case WasmOpcode_f32_min: |
| 2018 | | if (unreachable_depth == 0) { |
| 2019 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2020 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2021 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 2022 | | fprintf(out, "fminf(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 2023 | | } |
| 2024 | | break; |
| 2025 | | case WasmOpcode_f32_max: |
| 2026 | | if (unreachable_depth == 0) { |
| 2027 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2028 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2029 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 2030 | | fprintf(out, "fmaxf(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 2031 | | } |
| 2032 | | break; |
| 2033 | | case WasmOpcode_f32_copysign: |
| 2034 | | if (unreachable_depth == 0) { |
| 2035 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2036 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2037 | | FuncGen_stackPush(&fg, out, WasmValType_f32); |
| 2038 | | fprintf(out, "copysignf(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 2039 | | } |
| 2040 | | break; |
| 2041 | | |
| 2042 | | case WasmOpcode_f64_abs: |
| 2043 | | if (unreachable_depth == 0) { |
| 2044 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2045 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2046 | | fprintf(out, "fabs(l%" PRIu32 ");\n", lhs); |
| 2047 | | } |
| 2048 | | break; |
| 2049 | | case WasmOpcode_f64_neg: |
| 2050 | | if (unreachable_depth == 0) { |
| 2051 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2052 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2053 | | fprintf(out, "-l%" PRIu32 ";\n", lhs); |
| 2054 | | } |
| 2055 | | break; |
| 2056 | | case WasmOpcode_f64_ceil: |
| 2057 | | if (unreachable_depth == 0) { |
| 2058 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2059 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2060 | | fprintf(out, "ceil(l%" PRIu32 ");\n", lhs); |
| 2061 | | } |
| 2062 | | break; |
| 2063 | | case WasmOpcode_f64_floor: |
| 2064 | | if (unreachable_depth == 0) { |
| 2065 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2066 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2067 | | fprintf(out, "floor(l%" PRIu32 ");\n", lhs); |
| 2068 | | } |
| 2069 | | break; |
| 2070 | | case WasmOpcode_f64_trunc: |
| 2071 | | if (unreachable_depth == 0) { |
| 2072 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2073 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2074 | | fprintf(out, "trunc(l%" PRIu32 ");\n", lhs); |
| 2075 | | } |
| 2076 | | break; |
| 2077 | | case WasmOpcode_f64_nearest: |
| 2078 | | if (unreachable_depth == 0) { |
| 2079 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2080 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2081 | | fprintf(out, "round(l%" PRIu32 ");\n", lhs); |
| 2082 | | } |
| 2083 | | break; |
| 2084 | | case WasmOpcode_f64_sqrt: |
| 2085 | | if (unreachable_depth == 0) { |
| 2086 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2087 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2088 | | fprintf(out, "sqrt(l%" PRIu32 ");\n", lhs); |
| 2089 | | } |
| 2090 | | break; |
| 2091 | | case WasmOpcode_f64_add: |
| 2092 | | if (unreachable_depth == 0) { |
| 2093 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2094 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2095 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2096 | | fprintf(out, "l%" PRIu32 " + l%" PRIu32 ";\n", lhs, rhs); |
| 2097 | | } |
| 2098 | | break; |
| 2099 | | case WasmOpcode_f64_sub: |
| 2100 | | if (unreachable_depth == 0) { |
| 2101 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2102 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2103 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2104 | | fprintf(out, "l%" PRIu32 " - l%" PRIu32 ";\n", lhs, rhs); |
| 2105 | | } |
| 2106 | | break; |
| 2107 | | case WasmOpcode_f64_mul: |
| 2108 | | if (unreachable_depth == 0) { |
| 2109 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2110 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2111 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2112 | | fprintf(out, "l%" PRIu32 " * l%" PRIu32 ";\n", lhs, rhs); |
| 2113 | | } |
| 2114 | | break; |
| 2115 | | case WasmOpcode_f64_div: |
| 2116 | | if (unreachable_depth == 0) { |
| 2117 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2118 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2119 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2120 | | fprintf(out, "l%" PRIu32 " / l%" PRIu32 ";\n", lhs, rhs); |
| 2121 | | } |
| 2122 | | break; |
| 2123 | | case WasmOpcode_f64_min: |
| 2124 | | if (unreachable_depth == 0) { |
| 2125 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2126 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2127 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2128 | | fprintf(out, "fmin(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 2129 | | } |
| 2130 | | break; |
| 2131 | | case WasmOpcode_f64_max: |
| 2132 | | if (unreachable_depth == 0) { |
| 2133 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2134 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2135 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2136 | | fprintf(out, "fmax(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 2137 | | } |
| 2138 | | break; |
| 2139 | | case WasmOpcode_f64_copysign: |
| 2140 | | if (unreachable_depth == 0) { |
| 2141 | | uint32_t rhs = FuncGen_stackPop(&fg); |
| 2142 | | uint32_t lhs = FuncGen_stackPop(&fg); |
| 2143 | | FuncGen_stackPush(&fg, out, WasmValType_f64); |
| 2144 | | fprintf(out, "copysign(l%" PRIu32 ", l%" PRIu32 ");\n", lhs, rhs); |
| 1830 | uint32_t lhs = FuncGen_stackAt(&fg, 0); |
| 1831 | const char *function; |
| 1832 | switch (opcode) { |
| 1833 | case WasmOpcode_f32_min: function = "fminf"; break; |
| 1834 | case WasmOpcode_f32_max: function = "fmaxf"; break; |
| 1835 | case WasmOpcode_f32_copysign: function = "copysignf"; break; |
| 1836 | case WasmOpcode_f64_min: function = "fmin"; break; |
| 1837 | case WasmOpcode_f64_max: function = "fmax"; break; |
| 1838 | case WasmOpcode_f64_copysign: function = "copysign"; break; |
| 1839 | default: panic("unreachable"); |
| 1840 | } |
| 1841 | FuncGen_indent(&fg, out); |
| 1842 | fprintf(out, "l%" PRIu32 " = %s(l%" PRIu32 ", l%" PRIu32 ");\n", |
| 1843 | lhs, function, lhs, rhs); |
| 2145 | 1844 | } |
| 2146 | 1845 | break; |
| 2147 | 1846 | |