<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 24, 2015 at 2:59 PM, JF Bastien via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jfb<br>
Date: Mon Aug 24 16:59:51 2015<br>
New Revision: 245882<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=245882&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=245882&view=rev</a><br>
Log:<br>
call<br></blockquote><div><br>(guess you forgot to update this before committing - perhaps you could just provide a follow up email here with a more descriptive commit message?)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Added:<br>
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def<br>
      - copied, changed from r245878, llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td<br>
    llvm/trunk/test/CodeGen/WebAssembly/call.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp<br>
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h<br>
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp<br>
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h<br>
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td<br>
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Mon Aug 24 16:59:51 2015<br>
@@ -44,3 +44,16 @@ void WebAssemblyInstPrinter::printInst(c<br>
   printInstruction(MI, OS);<br>
   printAnnotation(OS, Annot);<br>
 }<br>
+<br>
+void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,<br>
+                                          raw_ostream &O) {<br>
+  const MCOperand &Op = MI->getOperand(OpNo);<br>
+  if (Op.isReg())<br>
+    O << getRegisterName(Op.getReg());<br>
+  else if (Op.isImm())<br>
+    O << '#' << Op.getImm();<br>
+  else {<br>
+    assert(Op.isExpr() && "unknown operand kind in printOperand");<br>
+    Op.getExpr()->print(O, &MAI);<br>
+  }<br>
+}<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Mon Aug 24 16:59:51 2015<br>
@@ -32,6 +32,9 @@ public:<br>
   void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,<br>
                  const MCSubtargetInfo &STI) override;<br>
<br>
+  // Used by tblegen code.<br>
+  void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);<br>
+<br>
   // Autogenerated by tblgen.<br>
   void printInstruction(const MCInst *MI, raw_ostream &O);<br>
   static const char *getRegisterName(unsigned RegNo);<br>
<br>
Copied: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def (from r245878, llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def?p2=llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def&p1=llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td&r1=245878&r2=245882&rev=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def?p2=llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def&p1=llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td&r1=245878&r2=245882&rev=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def Mon Aug 24 16:59:51 2015<br>
@@ -1,4 +1,4 @@<br>
-//===- WebAssemblyInstrCall.td-WebAssembly Call codegen support -*- tablegen -*-<br>
+//- WebAssemblyISD.def - WebAssembly ISD ---------------------------*- C++ -*-//<br>
 //<br>
 //                     The LLVM Compiler Infrastructure<br>
 //<br>
@@ -8,14 +8,12 @@<br>
 //===----------------------------------------------------------------------===//<br>
 ///<br>
 /// \file<br>
-/// \brief WebAssembly Call operand code-gen constructs.<br>
+/// \brief This file describes the various WebAssembly ISD node types.<br>
 ///<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-/*<br>
- * TODO(jfb): Add the following.<br>
- *<br>
- * call_direct: call function directly<br>
- * call_indirect: call function indirectly<br>
- * addressof: obtain a function pointer value for a given function<br>
- */<br>
+// NOTE: NO INCLUDE GUARD DESIRED!<br>
+<br>
+HANDLE_NODETYPE(CALL)<br>
+HANDLE_NODETYPE(RETURN)<br>
+HANDLE_NODETYPE(ARGUMENT)<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Mon Aug 24 16:59:51 2015<br>
@@ -19,6 +19,7 @@<br>
 #include "WebAssemblyTargetMachine.h"<br>
 #include "WebAssemblyTargetObjectFile.h"<br>
 #include "llvm/CodeGen/Analysis.h"<br>
+#include "llvm/CodeGen/CallingConvLower.h"<br>
 #include "llvm/CodeGen/MachineRegisterInfo.h"<br>
 #include "llvm/CodeGen/SelectionDAG.h"<br>
 #include "llvm/IR/DiagnosticInfo.h"<br>
@@ -164,9 +165,13 @@ MVT WebAssemblyTargetLowering::getScalar<br>
 const char *<br>
 WebAssemblyTargetLowering::getTargetNodeName(unsigned Opcode) const {<br>
   switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {<br>
-  case WebAssemblyISD::FIRST_NUMBER: break;<br>
-  case WebAssemblyISD::RETURN: return "WebAssemblyISD::RETURN";<br>
-  case WebAssemblyISD::ARGUMENT: return "WebAssemblyISD::ARGUMENT";<br>
+  case WebAssemblyISD::FIRST_NUMBER:<br>
+    break;<br>
+#define HANDLE_NODETYPE(NODE)                                                  \<br>
+  case WebAssemblyISD::NODE:                                                   \<br>
+    return "WebAssemblyISD::" #NODE;<br>
+#include "WebAssemblyISD.def"<br>
+#undef HANDLE_NODETYPE<br>
   }<br>
   return nullptr;<br>
 }<br>
@@ -185,6 +190,68 @@ static void fail(SDLoc DL, SelectionDAG<br>
       DiagnosticInfoUnsupported(DL, *MF.getFunction(), msg, SDValue()));<br>
 }<br>
<br>
+SDValue<br>
+WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,<br>
+                                     SmallVectorImpl<SDValue> &InVals) const {<br>
+  SelectionDAG &DAG = CLI.DAG;<br>
+  SDLoc DL = CLI.DL;<br>
+  SDValue Chain = CLI.Chain;<br>
+  SDValue Callee = CLI.Callee;<br>
+  MachineFunction &MF = DAG.getMachineFunction();<br>
+<br>
+  CallingConv::ID CallConv = CLI.CallConv;<br>
+  if (CallConv != CallingConv::C)<br>
+    fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");<br>
+  if (CLI.IsTailCall || MF.getTarget().Options.GuaranteedTailCallOpt)<br>
+    fail(DL, DAG, "WebAssembly doesn't support tail call yet");<br>
+  if (CLI.IsPatchPoint)<br>
+    fail(DL, DAG, "WebAssembly doesn't support patch point yet");<br>
+<br>
+  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;<br>
+  SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;<br>
+  Type *retTy = CLI.RetTy;<br>
+  bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();<br>
+  if (IsStructRet)<br>
+    fail(DL, DAG, "WebAssembly doesn't support struct return yet");<br>
+  if (Outs.size() > 1)<br>
+    fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");<br>
+<br>
+  SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;<br>
+  ArgListTy &Args = CLI.getArgs();<br>
+  bool IsVarArg = CLI.IsVarArg;<br>
+  if (IsVarArg)<br>
+    fail(DL, DAG, "WebAssembly doesn't support varargs yet");<br>
+  // Analyze operands of the call, assigning locations to each operand.<br>
+  SmallVector<CCValAssign, 16> ArgLocs;<br>
+  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());<br>
+  unsigned NumBytes = CCInfo.getNextStackOffset();<br>
+<br>
+  auto PtrVT = getPointerTy(MF.getDataLayout());<br>
+  auto Zero = DAG.getConstant(0, CLI.DL, PtrVT, true);<br>
+  auto NB = DAG.getConstant(NumBytes, CLI.DL, PtrVT, true);<br>
+  Chain = DAG.getCALLSEQ_START(Chain, NB, CLI.DL);<br>
+<br>
+  SmallVector<SDValue, 16> Ops;<br>
+  Ops.push_back(Chain);<br>
+  Ops.push_back(CLI.Callee);<br>
+  Ops.append(CLI.OutVals.begin(), CLI.OutVals.end());<br>
+<br>
+  SmallVector<EVT, 8> Tys;<br>
+  for (const auto &In : CLI.Ins)<br>
+    Tys.push_back(In.VT);<br>
+  Tys.push_back(MVT::Other);<br>
+  SDVTList TyList = CLI.DAG.getVTList(Tys);<br>
+  SDValue Res = CLI.DAG.getNode(WebAssemblyISD::CALL, CLI.DL, TyList, Ops);<br>
+  InVals.push_back(Res);<br>
+  Chain = Res.getValue(1);<br>
+<br>
+  // FIXME: handle CLI.RetSExt and CLI.RetZExt?<br>
+<br>
+  Chain = CLI.DAG.getCALLSEQ_END(Chain, NB, Zero, SDValue(), CLI.DL);<br>
+<br>
+  return Chain;<br>
+}<br>
+<br>
 bool WebAssemblyTargetLowering::CanLowerReturn(<br>
     CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,<br>
     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Mon Aug 24 16:59:51 2015<br>
@@ -24,9 +24,9 @@ namespace WebAssemblyISD {<br>
<br>
 enum NodeType : unsigned {<br>
   FIRST_NUMBER = ISD::BUILTIN_OP_END,<br>
-  RETURN,<br>
-  ARGUMENT,<br>
-<br>
+#define HANDLE_NODETYPE(NODE) NODE,<br>
+#include "WebAssemblyISD.def"<br>
+#undef HANDLE_NODETYPE<br>
   // add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...<br>
 };<br>
<br>
@@ -52,6 +52,9 @@ private:<br>
<br>
   const char *getTargetNodeName(unsigned Opcode) const override;<br>
<br>
+  SDValue LowerCall(CallLoweringInfo &CLI,<br>
+                    SmallVectorImpl<SDValue> &InVals) const override;<br>
+<br>
   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,<br>
                       bool isVarArg,<br>
                       const SmallVectorImpl<ISD::OutputArg> &Outs,<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td Mon Aug 24 16:59:51 2015<br>
@@ -12,6 +12,29 @@<br>
 ///<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+// The call sequence start/end LLVM-isms isn't useful to WebAssembly since it's<br>
+// a virtual ISA.<br>
+<br>
+// FIXME make noop?<br>
+//def : Pat<(WebAssemblycallseq_start timm), (i32 (IMPLICIT_DEF))>;<br>
+//def : Pat<(WebAssemblycallseq_end timm, timm), (i32 (IMPLICIT_DEF))>;<br>
+<br>
+def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>]>;<br>
+def SDT_WebAssemblyCallSeqEnd :<br>
+    SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;<br>
+def WebAssemblycallseq_start :<br>
+    SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart,<br>
+           [SDNPHasChain, SDNPOutGlue]>;<br>
+def WebAssemblycallseq_end :<br>
+    SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd,<br>
+           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;<br>
+def : Pseudo<(outs), (ins i64imm:$amt),<br>
+             [(WebAssemblycallseq_start timm:$amt)],<br>
+             "#ADJCALLSTACKDOWN $amt">;<br>
+def : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),<br>
+             [(WebAssemblycallseq_end timm:$amt1, timm:$amt2)],<br>
+            "#ADJCALLSTACKUP $amt1 $amt2">;<br>
+<br>
 /*<br>
  * TODO(jfb): Add the following.<br>
  *<br>
<br>
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=245882&r1=245881&r2=245882&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=245882&r1=245881&r2=245882&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)<br>
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Mon Aug 24 16:59:51 2015<br>
@@ -12,7 +12,7 @@<br>
 ///<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-// WebAssembly Instruction Format<br>
+// WebAssembly Instruction Format.<br>
 class WebAssemblyInst<string cstr> : Instruction {<br>
   field bits<0> Inst; // Instruction encoding.<br>
   let Namespace   = "WebAssembly";<br>
@@ -20,7 +20,7 @@ class WebAssemblyInst<string cstr> : Ins<br>
   let Constraints = cstr;<br>
 }<br>
<br>
-// Normal instructions<br>
+// Normal instructions.<br>
 class I<dag oops, dag iops, list<dag> pattern, string cstr = ""><br>
     : WebAssemblyInst<cstr> {<br>
   dag OutOperandList = oops;<br>
@@ -28,6 +28,14 @@ class I<dag oops, dag iops, list<dag> pa<br>
   let Pattern        = pattern;<br>
 }<br>
<br>
+// Pseudo instructions.<br>
+class Pseudo<dag oops, dag iops, list<dag> pattern, string asmstr,<br>
+             string cstr = ""><br>
+  : I<oops, iops, pattern, cstr> {<br>
+  let isPseudo  = 1;<br>
+  let AsmString = asmstr;<br>
+}<br>
+<br>
 // Unary and binary instructions, for the local types that WebAssembly supports.<br>
 multiclass UnaryInt<SDNode node> {<br>
   def _I32 : I<(outs Int32:$dst), (ins Int32:$src),<br>
<br>
Added: llvm/trunk/test/CodeGen/WebAssembly/call.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/call.ll?rev=245882&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/call.ll?rev=245882&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/WebAssembly/call.ll (added)<br>
+++ llvm/trunk/test/CodeGen/WebAssembly/call.ll Mon Aug 24 16:59:51 2015<br>
@@ -0,0 +1,22 @@<br>
+; RUN: llc < %s -asm-verbose=false | FileCheck %s<br>
+<br>
+; Test that basic call operations assemble as expected.<br>
+<br>
+target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"<br>
+target triple = "wasm32-unknown-unknown"<br>
+<br>
+declare void @nullary()<br>
+<br>
+; CHECK-LABEL: call_nullary:<br>
+; CHECK-NEXT: (call @foo)<br>
+; CHECK-NEXT: (return)<br>
+define void @call_nullary() {<br>
+  call void @nullary()<br>
+  ret void<br>
+}<br>
+<br>
+<br>
+; tail call<br>
+; multiple args<br>
+; interesting returns (int, float, struct, multiple)<br>
+; vararg<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>