WebAssembly: floating-point comparisons
[oota-llvm.git] / lib / Target / WebAssembly / WebAssemblyISelLowering.cpp
index 639e19a52dc2a7c9349e20e447d501547c2d1ab3..21a322241a8b2fdd8c7c95fd746a4cc6eb550a29 100644 (file)
@@ -92,6 +92,8 @@ int DiagnosticInfoUnsupported::KindID = 0;
 WebAssemblyTargetLowering::WebAssemblyTargetLowering(
     const TargetMachine &TM, const WebAssemblySubtarget &STI)
     : TargetLowering(TM), Subtarget(&STI) {
+  // Booleans always contain 0 or 1.
+  setBooleanContents(ZeroOrOneBooleanContent);
   // WebAssembly does not produce floating-point exceptions on normal floating
   // point operations.
   setHasFloatingPointExceptions(false);
@@ -108,7 +110,31 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
   // Compute derived properties from the register classes.
   computeRegisterProperties(Subtarget->getRegisterInfo());
 
-  // FIXME: setOperationAction...
+  // FIXME: many setOperationAction are missing...
+
+  for (auto T : {MVT::f32, MVT::f64}) {
+    // Don't expand the floating-point types to constant pools.
+    setOperationAction(ISD::ConstantFP, T, Legal);
+    // Expand floating-point comparisons.
+    for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
+                    ISD::SETULT, ISD::SETULE, ISD::SETUGT, ISD::SETUGE})
+      setCondCodeAction(CC, T, Expand);
+  }
+}
+
+MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout &DL,
+                                                      EVT VT) const {
+  return VT.getSimpleVT();
+}
+
+const char *
+WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {
+  switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
+  case WebAssemblyISD::FIRST_NUMBER: break;
+  case WebAssemblyISD::RETURN: return "WebAssemblyISD::RETURN";
+  case WebAssemblyISD::ARGUMENT: return "WebAssemblyISD::ARGUMENT";
+  }
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -146,8 +172,7 @@ SDValue WebAssemblyTargetLowering::LowerReturn(
 
   SmallVector<SDValue, 4> RetOps(1, Chain);
   RetOps.append(OutVals.begin(), OutVals.end());
-  const SDValue Ops[] = {Chain, OutVals.front()};
-  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, Ops);
+  Chain = DAG.getNode(WebAssemblyISD::RETURN, DL, MVT::Other, RetOps);
 
   return Chain;
 }
@@ -189,13 +214,13 @@ SDValue WebAssemblyTargetLowering::LowerFormalArguments(
       fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments");
     if (In.Flags.isSplit())
       fail(DL, DAG, "WebAssembly hasn't implemented split arguments");
-    if (In.VT != MVT::i32)
-      fail(DL, DAG, "WebAssembly hasn't implemented non-i32 arguments");
-    if (!In.Used)
-      fail(DL, DAG, "WebAssembly hasn't implemented unused arguments");
     // FIXME Do something with In.getOrigAlign()?
-    InVals.push_back(DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
-                                 DAG.getTargetConstant(ArgNo++, DL, MVT::i32)));
+    InVals.push_back(
+        In.Used
+            ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT,
+                          DAG.getTargetConstant(ArgNo, DL, MVT::i32))
+            : DAG.getNode(ISD::UNDEF, DL, In.VT));
+    ++ArgNo;
   }
 
   return Chain;