[llvm] r245887 - WebAssembly: Implement call
JF Bastien via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 15:16:50 PDT 2015
Author: jfb
Date: Mon Aug 24 17:16:48 2015
New Revision: 245887
URL: http://llvm.org/viewvc/llvm-project?rev=245887&view=rev
Log:
WebAssembly: Implement call
Summary: Support function calls.
Reviewers: sunfish, sunfishcode
Subscribers: sunfishcode, jfb, llvm-commits
Differential revision: http://reviews.llvm.org/D12219
Added:
llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
- copied, changed from r245886, llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
Modified:
llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
llvm/trunk/test/CodeGen/WebAssembly/call.ll
Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Mon Aug 24 17:16:48 2015
@@ -44,3 +44,16 @@ void WebAssemblyInstPrinter::printInst(c
printInstruction(MI, OS);
printAnnotation(OS, Annot);
}
+
+void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isReg())
+ O << getRegisterName(Op.getReg());
+ else if (Op.isImm())
+ O << '#' << Op.getImm();
+ else {
+ assert(Op.isExpr() && "unknown operand kind in printOperand");
+ Op.getExpr()->print(O, &MAI);
+ }
+}
Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Mon Aug 24 17:16:48 2015
@@ -32,6 +32,9 @@ public:
void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,
const MCSubtargetInfo &STI) override;
+ // Used by tblegen code.
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Mon Aug 24 17:16:48 2015
@@ -84,7 +84,10 @@ static SmallString<32> Name(const WebAss
return SmallString<32>(&N[0], &N[End]);
}
+static std::string toSymbol(StringRef S) { return ("$" + S).str(); }
+
void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n');
SmallString<128> Str;
raw_svector_ostream OS(Str);
@@ -132,6 +135,9 @@ void WebAssemblyAsmPrinter::EmitInstruct
assert(Written < BufBytes);
OS << ' ' << buf;
} break;
+ case MachineOperand::MO_GlobalAddress: {
+ OS << ' ' << toSymbol(MO.getGlobal()->getName());
+ } break;
}
OS << ')';
Copied: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def (from r245886, llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td)
URL: 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=245886&r2=245887&rev=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def Mon Aug 24 17:16:48 2015
@@ -1,4 +1,4 @@
-//===- WebAssemblyInstrCall.td-WebAssembly Call codegen support -*- tablegen -*-
+//- WebAssemblyISD.def - WebAssembly ISD ---------------------------*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
@@ -8,14 +8,15 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief WebAssembly Call operand code-gen constructs.
+/// \brief This file describes the various WebAssembly ISD node types.
///
//===----------------------------------------------------------------------===//
-/*
- * TODO(jfb): Add the following.
- *
- * call_direct: call function directly
- * call_indirect: call function indirectly
- * addressof: obtain a function pointer value for a given function
- */
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+HANDLE_NODETYPE(CALL)
+HANDLE_NODETYPE(RETURN)
+HANDLE_NODETYPE(ARGUMENT)
+HANDLE_NODETYPE(Wrapper)
+
+// add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Mon Aug 24 17:16:48 2015
@@ -19,6 +19,7 @@
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyTargetObjectFile.h"
#include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/IR/DiagnosticInfo.h"
@@ -92,6 +93,8 @@ int DiagnosticInfoUnsupported::KindID =
WebAssemblyTargetLowering::WebAssemblyTargetLowering(
const TargetMachine &TM, const WebAssemblySubtarget &STI)
: TargetLowering(TM), Subtarget(&STI) {
+ auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32;
+
// Booleans always contain 0 or 1.
setBooleanContents(ZeroOrOneBooleanContent);
// WebAssembly does not produce floating-point exceptions on normal floating
@@ -112,6 +115,8 @@ WebAssemblyTargetLowering::WebAssemblyTa
// FIXME: many setOperationAction are missing...
+ setOperationAction(ISD::GlobalAddress, MVTPtr, Custom);
+
for (auto T : {MVT::f32, MVT::f64}) {
// Don't expand the floating-point types to constant pools.
setOperationAction(ISD::ConstantFP, T, Legal);
@@ -156,6 +161,13 @@ FastISel *WebAssemblyTargetLowering::cre
return WebAssembly::createFastISel(FuncInfo, LibInfo);
}
+bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
+ const GlobalAddressSDNode *GA) const {
+ // The WebAssembly target doesn't support folding offsets into global
+ // addresses.
+ return false;
+}
+
MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout &DL,
EVT VT) const {
return VT.getSimpleVT();
@@ -164,9 +176,13 @@ MVT WebAssemblyTargetLowering::getScalar
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";
+ case WebAssemblyISD::FIRST_NUMBER:
+ break;
+#define HANDLE_NODETYPE(NODE) \
+ case WebAssemblyISD::NODE: \
+ return "WebAssemblyISD::" #NODE;
+#include "WebAssemblyISD.def"
+#undef HANDLE_NODETYPE
}
return nullptr;
}
@@ -185,7 +201,6 @@ static void fail(SDLoc DL, SelectionDAG
DiagnosticInfoUnsupported(DL, *MF.getFunction(), msg, SDValue()));
}
-<<<<<<< HEAD
SDValue
WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
@@ -205,7 +220,6 @@ WebAssemblyTargetLowering::LowerCall(Cal
SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- Type *retTy = CLI.RetTy;
bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
if (IsStructRet)
fail(DL, DAG, "WebAssembly doesn't support struct return yet");
@@ -213,7 +227,6 @@ WebAssemblyTargetLowering::LowerCall(Cal
fail(DL, DAG, "WebAssembly doesn't support more than 1 returned value yet");
SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
- ArgListTy &Args = CLI.getArgs();
bool IsVarArg = CLI.IsVarArg;
if (IsVarArg)
fail(DL, DAG, "WebAssembly doesn't support varargs yet");
@@ -223,33 +236,35 @@ WebAssemblyTargetLowering::LowerCall(Cal
unsigned NumBytes = CCInfo.getNextStackOffset();
auto PtrVT = getPointerTy(MF.getDataLayout());
- auto Zero = DAG.getConstant(0, CLI.DL, PtrVT, true);
- auto NB = DAG.getConstant(NumBytes, CLI.DL, PtrVT, true);
- Chain = DAG.getCALLSEQ_START(Chain, NB, CLI.DL);
+ auto Zero = DAG.getConstant(0, DL, PtrVT, true);
+ auto NB = DAG.getConstant(NumBytes, DL, PtrVT, true);
+ Chain = DAG.getCALLSEQ_START(Chain, NB, DL);
SmallVector<SDValue, 16> Ops;
Ops.push_back(Chain);
- Ops.push_back(CLI.Callee);
- Ops.append(CLI.OutVals.begin(), CLI.OutVals.end());
+ Ops.push_back(Callee);
+ Ops.append(OutVals.begin(), OutVals.end());
SmallVector<EVT, 8> Tys;
- for (const auto &In : CLI.Ins)
+ for (const auto &In : Ins)
Tys.push_back(In.VT);
Tys.push_back(MVT::Other);
- SDVTList TyList = CLI.DAG.getVTList(Tys);
- SDValue Res = CLI.DAG.getNode(WebAssemblyISD::CALL, CLI.DL, TyList, Ops);
- InVals.push_back(Res);
- Chain = Res.getValue(1);
+ SDVTList TyList = DAG.getVTList(Tys);
+ SDValue Res = DAG.getNode(WebAssemblyISD::CALL, DL, TyList, Ops);
+ if (Ins.empty()) {
+ Chain = Res;
+ } else {
+ InVals.push_back(Res);
+ Chain = Res.getValue(1);
+ }
// FIXME: handle CLI.RetSExt and CLI.RetZExt?
- Chain = CLI.DAG.getCALLSEQ_END(Chain, NB, Zero, SDValue(), CLI.DL);
+ Chain = DAG.getCALLSEQ_END(Chain, NB, Zero, SDValue(), DL);
return Chain;
}
-=======
->>>>>>> parent of 03685a9... call
bool WebAssemblyTargetLowering::CanLowerReturn(
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
@@ -326,9 +341,34 @@ SDValue WebAssemblyTargetLowering::Lower
}
//===----------------------------------------------------------------------===//
-// Other Lowering Code
+// Custom lowering hooks.
//===----------------------------------------------------------------------===//
+SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
+ SelectionDAG &DAG) const {
+ switch (Op.getOpcode()) {
+ default:
+ llvm_unreachable("unimplemented operation lowering");
+ return SDValue();
+ case ISD::GlobalAddress:
+ return LowerGlobalAddress(Op, DAG);
+ }
+}
+
+SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ const auto *GA = cast<GlobalAddressSDNode>(Op);
+ EVT VT = Op.getValueType();
+ assert(GA->getOffset() == 0 &&
+ "offsets on global addresses are forbidden by isOffsetFoldingLegal");
+ assert(GA->getTargetFlags() == 0 && "WebAssembly doesn't set target flags");
+ if (GA->getAddressSpace() != 0)
+ fail(DL, DAG, "WebAssembly only expects the 0 address space");
+ return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
+ DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT));
+}
+
//===----------------------------------------------------------------------===//
// WebAssembly Optimization Hooks
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Mon Aug 24 17:16:48 2015
@@ -24,10 +24,9 @@ namespace WebAssemblyISD {
enum NodeType : unsigned {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
- RETURN,
- ARGUMENT,
-
- // add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...
+#define HANDLE_NODETYPE(NODE) NODE,
+#include "WebAssemblyISD.def"
+#undef HANDLE_NODETYPE
};
} // end namespace WebAssemblyISD
@@ -47,26 +46,29 @@ private:
FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
const TargetLibraryInfo *LibInfo) const override;
-
+ bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override;
-
const char *getTargetNodeName(unsigned Opcode) const override;
+ SDValue LowerCall(CallLoweringInfo &CLI,
+ SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const override;
-
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals, SDLoc dl,
SelectionDAG &DAG) const override;
-
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
+
+ // Custom lowering hooks.
+ SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
+ SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
};
namespace WebAssembly {
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td Mon Aug 24 17:16:48 2015
@@ -12,6 +12,27 @@
///
//===----------------------------------------------------------------------===//
+// The call sequence start/end LLVM-isms isn't useful to WebAssembly since it's
+// a virtual ISA.
+let isCodeGenOnly = 1 in {
+def : I<(outs), (ins i64imm:$amt),
+ [(WebAssemblycallseq_start timm:$amt)]>;
+def : I<(outs), (ins i64imm:$amt1, i64imm:$amt2),
+ [(WebAssemblycallseq_end timm:$amt1, timm:$amt2)]>;
+} // isCodeGenOnly = 1
+
+multiclass CALL<WebAssemblyRegClass vt> {
+ def CALL_#vt : I<(outs vt:$dst), (ins Int32:$callee, variable_ops),
+ [(set vt:$dst, (WebAssemblycall Int32:$callee))]>;
+}
+let Uses = [SP32, SP64], isCall = 1 in {
+ defm : CALL<Int32>;
+ defm : CALL<Int64>;
+ defm : CALL<Float32>;
+ defm : CALL<Float64>;
+ // FIXME: void.
+} // Uses = [SP32,SP64], isCall = 1
+
/*
* TODO(jfb): Add the following.
*
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Mon Aug 24 17:16:48 2015
@@ -28,12 +28,10 @@
multiclass RETURN<WebAssemblyRegClass vt> {
def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)]>;
}
-let hasSideEffects = 1, isReturn = 1, isTerminator = 1, hasCtrlDep = 1,
- isBarrier = 1 in {
+let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
defm : RETURN<Int32>;
defm : RETURN<Int64>;
defm : RETURN<Float32>;
defm : RETURN<Float64>;
def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)]>;
-} // hasSideEffects = 1, isReturn = 1, isTerminator = 1, hasCtrlDep = 1,
- // isBarrier = 1
+} // isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Mon Aug 24 17:16:48 2015
@@ -12,7 +12,7 @@
///
//===----------------------------------------------------------------------===//
-// WebAssembly Instruction Format
+// WebAssembly Instruction Format.
class WebAssemblyInst<string cstr> : Instruction {
field bits<0> Inst; // Instruction encoding.
let Namespace = "WebAssembly";
@@ -20,7 +20,7 @@ class WebAssemblyInst<string cstr> : Ins
let Constraints = cstr;
}
-// Normal instructions
+// Normal instructions.
class I<dag oops, dag iops, list<dag> pattern, string cstr = "">
: WebAssemblyInst<cstr> {
dag OutOperandList = oops;
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Mon Aug 24 17:16:48 2015
@@ -25,18 +25,34 @@ def HasSIMD128 : Predicate<"Subtarget->h
// WebAssembly-specific DAG Node Types.
//===----------------------------------------------------------------------===//
+def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>]>;
+def SDT_WebAssemblyCallSeqEnd :
+ SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
+def SDT_WebAssemblyCall : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>;
def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>;
def SDT_WebAssemblyReturn : SDTypeProfile<0, -1, []>;
+def SDT_WebAssemblyWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
+ SDTCisPtrTy<0>]>;
//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Nodes.
//===----------------------------------------------------------------------===//
+def WebAssemblycallseq_start :
+ SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart,
+ [SDNPHasChain, SDNPOutGlue]>;
+def WebAssemblycallseq_end :
+ SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
+def WebAssemblycall : SDNode<"WebAssemblyISD::CALL",
+ SDT_WebAssemblyCall,
+ [SDNPHasChain, SDNPVariadic]>;
def WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT",
SDT_WebAssemblyArgument>;
def WebAssemblyreturn : SDNode<"WebAssemblyISD::RETURN",
- SDT_WebAssemblyReturn,
- [SDNPHasChain, SDNPSideEffect]>;
+ SDT_WebAssemblyReturn, [SDNPHasChain]>;
+def WebAssemblywrapper : SDNode<"WebAssemblyISD::Wrapper",
+ SDT_WebAssemblyWrapper>;
//===----------------------------------------------------------------------===//
// WebAssembly-specific Operands.
@@ -49,6 +65,8 @@ def WebAssemblyreturn : SDNode<"WebAss
* set_local: set the current value of a local variable
*/
+def global : Operand<iPTR>;
+
//===----------------------------------------------------------------------===//
// WebAssembly Instruction Format Definitions.
//===----------------------------------------------------------------------===//
@@ -74,6 +92,10 @@ def Immediate_F32 : I<(outs Float32:$res
def Immediate_F64 : I<(outs Float64:$res), (ins f64imm:$imm),
[(set Float64:$res, fpimm:$imm)]>;
+// Special types of immediates.
+def GLOBAL : I<(outs Int32:$dst), (ins global:$addr),
+ [(set Int32:$dst, (WebAssemblywrapper tglobaladdr:$addr))]>;
+
//===----------------------------------------------------------------------===//
// Additional sets of instructions.
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/test/CodeGen/WebAssembly/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/call.ll?rev=245887&r1=245886&r2=245887&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/call.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/call.ll Mon Aug 24 17:16:48 2015
@@ -5,18 +5,61 @@
target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"
target triple = "wasm32-unknown-unknown"
-declare void @nullary()
+declare i32 @i32_nullary()
+declare i32 @i32_unary(i32)
+declare i64 @i64_nullary()
+declare float @float_nullary()
+declare double @double_nullary()
-; CHECK-LABEL: call_nullary:
-; CHECK-NEXT: (call @foo)
-; CHECK-NEXT: (return)
-define void @call_nullary() {
- call void @nullary()
- ret void
+; CHECK-LABEL: call_i32_nullary:
+; CHECK-NEXT: (setlocal @0 (global $i32_nullary))
+; CHECK-NEXT: (setlocal @1 (call @0))
+; CHECK-NEXT: (return @1)
+define i32 @call_i32_nullary() {
+ %r = call i32 @i32_nullary()
+ ret i32 %r
}
+; CHECK-LABEL: call_i64_nullary:
+; CHECK-NEXT: (setlocal @0 (global $i64_nullary))
+; CHECK-NEXT: (setlocal @1 (call @0))
+; CHECK-NEXT: (return @1)
+define i64 @call_i64_nullary() {
+ %r = call i64 @i64_nullary()
+ ret i64 %r
+}
+
+; CHECK-LABEL: call_float_nullary:
+; CHECK-NEXT: (setlocal @0 (global $float_nullary))
+; CHECK-NEXT: (setlocal @1 (call @0))
+; CHECK-NEXT: (return @1)
+define float @call_float_nullary() {
+ %r = call float @float_nullary()
+ ret float %r
+}
+
+; CHECK-LABEL: call_double_nullary:
+; CHECK-NEXT: (setlocal @0 (global $double_nullary))
+; CHECK-NEXT: (setlocal @1 (call @0))
+; CHECK-NEXT: (return @1)
+define double @call_double_nullary() {
+ %r = call double @double_nullary()
+ ret double %r
+}
+
+; CHECK-LABEL: call_i32_unary:
+; CHECK-NEXT: (setlocal @0 (argument 0))
+; CHECK-NEXT: (setlocal @1 (global $i32_unary))
+; CHECK-NEXT: (setlocal @2 (call @1 @0))
+; CHECK-NEXT: (return @2)
+define i32 @call_i32_unary(i32 %a) {
+ %r = call i32 @i32_unary(i32 %a)
+ ret i32 %r
+}
-; tail call
-; multiple args
-; interesting returns (int, float, struct, multiple)
-; vararg
+; FIXME test the following:
+; - Functions without return.
+; - More argument combinations.
+; - Tail call.
+; - Interesting returns (struct, multiple).
+; - Vararg.
More information about the llvm-commits
mailing list