@@ -1400,6 +1400,12 @@ Ref Wasm2AsmBuilder::processFunctionBody(Function* func, IString result) {
14001400 visit (curr->value , EXPRESSION_RESULT)
14011401 );
14021402 break ;
1403+ case PromoteFloat32:
1404+ return makeAsmCoercion (visit (curr->value , EXPRESSION_RESULT),
1405+ ASM_DOUBLE);
1406+ case DemoteFloat64:
1407+ return makeAsmCoercion (visit (curr->value , EXPRESSION_RESULT),
1408+ ASM_FLOAT);
14031409 // TODO: more complex unary conversions
14041410 default :
14051411 std::cerr << " Unhandled unary float operator: " << curr
@@ -1438,112 +1444,181 @@ Ref Wasm2AsmBuilder::processFunctionBody(Function* func, IString result) {
14381444 Ref left = visit (curr->left , EXPRESSION_RESULT);
14391445 Ref right = visit (curr->right , EXPRESSION_RESULT);
14401446 Ref ret;
1441- switch (curr->op ) {
1442- case AddInt32:
1443- ret = ValueBuilder::makeBinary (left, PLUS, right);
1444- break ;
1445- case SubInt32:
1446- ret = ValueBuilder::makeBinary (left, MINUS, right);
1447- break ;
1448- case MulInt32: {
1449- if (curr->type == i32 ) {
1450- // TODO: when one operand is a small int, emit a multiply
1451- return ValueBuilder::makeCall (MATH_IMUL, left, right);
1452- } else {
1453- return ValueBuilder::makeBinary (left, MUL, right);
1447+ switch (curr->type ) {
1448+ case i32 : {
1449+ switch (curr->op ) {
1450+ case AddInt32:
1451+ ret = ValueBuilder::makeBinary (left, PLUS, right);
1452+ break ;
1453+ case SubInt32:
1454+ ret = ValueBuilder::makeBinary (left, MINUS, right);
1455+ break ;
1456+ case MulInt32: {
1457+ if (curr->type == i32 ) {
1458+ // TODO: when one operand is a small int, emit a multiply
1459+ return ValueBuilder::makeCall (MATH_IMUL, left, right);
1460+ } else {
1461+ return ValueBuilder::makeBinary (left, MUL, right);
1462+ }
1463+ }
1464+ case DivSInt32:
1465+ ret = ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), DIV,
1466+ makeSigning (right, ASM_SIGNED));
1467+ break ;
1468+ case DivUInt32:
1469+ ret = ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), DIV,
1470+ makeSigning (right, ASM_UNSIGNED));
1471+ break ;
1472+ case RemSInt32:
1473+ ret = ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), MOD,
1474+ makeSigning (right, ASM_SIGNED));
1475+ break ;
1476+ case RemUInt32:
1477+ ret = ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), MOD,
1478+ makeSigning (right, ASM_UNSIGNED));
1479+ break ;
1480+ case AndInt32:
1481+ ret = ValueBuilder::makeBinary (left, AND, right);
1482+ break ;
1483+ case OrInt32:
1484+ ret = ValueBuilder::makeBinary (left, OR, right);
1485+ break ;
1486+ case XorInt32:
1487+ ret = ValueBuilder::makeBinary (left, XOR, right);
1488+ break ;
1489+ case ShlInt32:
1490+ ret = ValueBuilder::makeBinary (left, LSHIFT, right);
1491+ break ;
1492+ case ShrUInt32:
1493+ ret = ValueBuilder::makeBinary (left, TRSHIFT, right);
1494+ break ;
1495+ case ShrSInt32:
1496+ ret = ValueBuilder::makeBinary (left, RSHIFT, right);
1497+ break ;
1498+ case EqInt32: {
1499+ // TODO: check if this condition is still valid/necessary
1500+ if (curr->left ->type == i32 ) {
1501+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), EQ,
1502+ makeSigning (right, ASM_SIGNED));
1503+ } else {
1504+ return ValueBuilder::makeBinary (left, EQ, right);
1505+ }
1506+ }
1507+ case NeInt32: {
1508+ if (curr->left ->type == i32 ) {
1509+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), NE,
1510+ makeSigning (right, ASM_SIGNED));
1511+ } else {
1512+ return ValueBuilder::makeBinary (left, NE, right);
1513+ }
1514+ }
1515+ case LtSInt32:
1516+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), LT,
1517+ makeSigning (right, ASM_SIGNED));
1518+ case LtUInt32:
1519+ return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), LT,
1520+ makeSigning (right, ASM_UNSIGNED));
1521+ case LeSInt32:
1522+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), LE,
1523+ makeSigning (right, ASM_SIGNED));
1524+ case LeUInt32:
1525+ return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), LE,
1526+ makeSigning (right, ASM_UNSIGNED));
1527+ case GtSInt32:
1528+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), GT,
1529+ makeSigning (right, ASM_SIGNED));
1530+ case GtUInt32:
1531+ return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), GT,
1532+ makeSigning (right, ASM_UNSIGNED));
1533+ case GeSInt32:
1534+ return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), GE,
1535+ makeSigning (right, ASM_SIGNED));
1536+ case GeUInt32:
1537+ return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), GE,
1538+ makeSigning (right, ASM_UNSIGNED));
1539+ case RotLInt32:
1540+ return makeSigning (ValueBuilder::makeCall (WASM_ROTL32, left, right),
1541+ ASM_SIGNED);
1542+ case RotRInt32:
1543+ return makeSigning (ValueBuilder::makeCall (WASM_ROTR32, left, right),
1544+ ASM_SIGNED);
1545+ case EqFloat32:
1546+ return makeAsmCoercion (ValueBuilder::makeBinary (left, EQ, right),
1547+ ASM_FLOAT);
1548+ case EqFloat64:
1549+ return ValueBuilder::makeBinary (left, EQ, right);
1550+ case NeFloat32:
1551+ return makeAsmCoercion (ValueBuilder::makeBinary (left, NE, right),
1552+ ASM_FLOAT);
1553+ case NeFloat64:
1554+ return ValueBuilder::makeBinary (left, NE, right);
1555+ case GeFloat32:
1556+ return makeAsmCoercion (ValueBuilder::makeBinary (left, GE, right),
1557+ ASM_FLOAT);
1558+ case GeFloat64:
1559+ return ValueBuilder::makeBinary (left, GE, right);
1560+ case GtFloat32:
1561+ return makeAsmCoercion (ValueBuilder::makeBinary (left, GT, right),
1562+ ASM_FLOAT);
1563+ case GtFloat64:
1564+ return ValueBuilder::makeBinary (left, GT, right);
1565+ case LeFloat32:
1566+ return makeAsmCoercion (ValueBuilder::makeBinary (left, LE, right),
1567+ ASM_FLOAT);
1568+ case LeFloat64:
1569+ return ValueBuilder::makeBinary (left, LE, right);
1570+ case LtFloat32:
1571+ return makeAsmCoercion (ValueBuilder::makeBinary (left, LT, right),
1572+ ASM_FLOAT);
1573+ case LtFloat64:
1574+ return ValueBuilder::makeBinary (left, LT, right);
1575+ default : {
1576+ std::cerr << " Unhandled i32 binary operator: " << curr << std::endl;
1577+ abort ();
1578+ }
14541579 }
1455- }
1456- case DivSInt32:
1457- ret = ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), DIV,
1458- makeSigning (right, ASM_SIGNED));
1459- break ;
1460- case DivUInt32:
1461- ret = ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), DIV,
1462- makeSigning (right, ASM_UNSIGNED));
1463- break ;
1464- case RemSInt32:
1465- ret = ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), MOD,
1466- makeSigning (right, ASM_SIGNED));
1467- break ;
1468- case RemUInt32:
1469- ret = ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), MOD,
1470- makeSigning (right, ASM_UNSIGNED));
1471- break ;
1472- case AndInt32:
1473- ret = ValueBuilder::makeBinary (left, AND, right);
1474- break ;
1475- case OrInt32:
1476- ret = ValueBuilder::makeBinary (left, OR, right);
1477- break ;
1478- case XorInt32:
1479- ret = ValueBuilder::makeBinary (left, XOR, right);
1480- break ;
1481- case ShlInt32:
1482- ret = ValueBuilder::makeBinary (left, LSHIFT, right);
14831580 break ;
1484- case ShrUInt32:
1485- ret = ValueBuilder::makeBinary (left, TRSHIFT, right);
1486- break ;
1487- case ShrSInt32:
1488- ret = ValueBuilder::makeBinary (left, RSHIFT, right);
1489- break ;
1490- case MinFloat32:
1491- ret = ValueBuilder::makeCall (MATH_MIN, left, right);
1492- break ;
1493- case MaxFloat32:
1494- ret = ValueBuilder::makeCall (MATH_MAX, left, right);
1495- break ;
1496- case EqInt32: {
1497- // TODO: check if this condition is still valid/necessary
1498- if (curr->left ->type == i32 ) {
1499- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), EQ,
1500- makeSigning (right, ASM_SIGNED));
1501- } else {
1502- return ValueBuilder::makeBinary (left, EQ, right);
1503- }
15041581 }
1505- case NeInt32: {
1506- if (curr->left ->type == i32 ) {
1507- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), NE,
1508- makeSigning (right, ASM_SIGNED));
1509- } else {
1510- return ValueBuilder::makeBinary (left, NE, right);
1582+ case f32 :
1583+ case f64 :
1584+ switch (curr->op ) {
1585+ case AddFloat32:
1586+ case AddFloat64:
1587+ ret = ValueBuilder::makeBinary (left, PLUS, right);
1588+ break ;
1589+ case SubFloat32:
1590+ case SubFloat64:
1591+ ret = ValueBuilder::makeBinary (left, MINUS, right);
1592+ break ;
1593+ case MulFloat32:
1594+ case MulFloat64:
1595+ ret = ValueBuilder::makeBinary (left, MUL, right);
1596+ break ;
1597+ case DivFloat32:
1598+ case DivFloat64:
1599+ ret = ValueBuilder::makeBinary (left, DIV, right);
1600+ break ;
1601+ case MinFloat32:
1602+ case MinFloat64:
1603+ ret = ValueBuilder::makeCall (MATH_MIN, left, right);
1604+ break ;
1605+ case MaxFloat32:
1606+ case MaxFloat64:
1607+ ret = ValueBuilder::makeCall (MATH_MAX, left, right);
1608+ break ;
1609+ case CopySignFloat32:
1610+ case CopySignFloat64:
1611+ default :
1612+ std::cerr << " Unhandled binary float operator: " << curr << std::endl;
1613+ abort ();
15111614 }
1512- }
1513- case LtSInt32:
1514- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), LT,
1515- makeSigning (right, ASM_SIGNED));
1516- case LtUInt32:
1517- return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), LT,
1518- makeSigning (right, ASM_UNSIGNED));
1519- case LeSInt32:
1520- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), LE,
1521- makeSigning (right, ASM_SIGNED));
1522- case LeUInt32:
1523- return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), LE,
1524- makeSigning (right, ASM_UNSIGNED));
1525- case GtSInt32:
1526- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), GT,
1527- makeSigning (right, ASM_SIGNED));
1528- case GtUInt32:
1529- return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), GT,
1530- makeSigning (right, ASM_UNSIGNED));
1531- case GeSInt32:
1532- return ValueBuilder::makeBinary (makeSigning (left, ASM_SIGNED), GE,
1533- makeSigning (right, ASM_SIGNED));
1534- case GeUInt32:
1535- return ValueBuilder::makeBinary (makeSigning (left, ASM_UNSIGNED), GE,
1536- makeSigning (right, ASM_UNSIGNED));
1537- case RotLInt32:
1538- return makeSigning (ValueBuilder::makeCall (WASM_ROTL32, left, right),
1539- ASM_SIGNED);
1540- case RotRInt32:
1541- return makeSigning (ValueBuilder::makeCall (WASM_ROTR32, left, right),
1542- ASM_SIGNED);
1543- default : {
1544- std::cerr << " Unhandled binary operator: " << curr << std::endl;
1615+ if (curr->type == f32 ) {
1616+ return makeAsmCoercion (ret, ASM_FLOAT);
1617+ }
1618+ return ret;
1619+ default :
1620+ std::cerr << " Unhandled type in binary: " << curr << std::endl;
15451621 abort ();
1546- }
15471622 }
15481623 return makeAsmCoercion (ret, wasmToAsmType (curr->type ));
15491624 }
0 commit comments