[llvm] r252997 - [WebAssembly] Inline asm support.
JF Bastien via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 16 16:51:10 PST 2015
(catching up on email post-vacation)
I'm a bit confused about this: the code looks like what I'd expect, but I
thought we weren't going to do inline asm. Could you clarify the usecase? I
thought we'd do calls to the embedders / syscalls through extern C
functions, so I'm not sure I get the use for inline asm.
On Thu, Nov 12, 2015 at 5:42 PM, Dan Gohman via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: djg
> Date: Thu Nov 12 19:42:29 2015
> New Revision: 252997
>
> URL: http://llvm.org/viewvc/llvm-project?rev=252997&view=rev
> Log:
> [WebAssembly] Inline asm support.
>
> Added:
> llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
> Modified:
> llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
> llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
> llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
> llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=252997&r1=252996&r2=252997&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Thu Nov 12
> 19:42:29 2015
> @@ -77,6 +77,12 @@ private:
> void EmitFunctionBodyStart() override;
> void EmitInstruction(const MachineInstr *MI) override;
> void EmitEndOfAsmFile(Module &M) override;
> + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
> + unsigned AsmVariant, const char *ExtraCode,
> + raw_ostream &OS) override;
> + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
> + unsigned AsmVariant, const char *ExtraCode,
> + raw_ostream &OS) override;
>
> std::string getRegTypeName(unsigned RegNo) const;
> const char *toString(MVT VT) const;
> @@ -275,6 +281,41 @@ void WebAssemblyAsmPrinter::EmitEndOfAsm
> OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
> }
>
> +bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
> + unsigned OpNo, unsigned
> AsmVariant,
> + const char *ExtraCode,
> + raw_ostream &OS) {
> + if (AsmVariant != 0)
> + report_fatal_error("There are no defined alternate asm variants");
> +
> + if (!ExtraCode) {
> + const MachineOperand &MO = MI->getOperand(OpNo);
> + if (MO.isImm())
> + OS << MO.getImm();
> + else
> + OS << regToString(MO);
> + return false;
> + }
> +
> + return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
> +}
> +
> +bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
> + unsigned OpNo,
> + unsigned AsmVariant,
> + const char *ExtraCode,
> + raw_ostream &OS) {
> + if (AsmVariant != 0)
> + report_fatal_error("There are no defined alternate asm variants");
> +
> + if (!ExtraCode) {
> + OS << regToString(MI->getOperand(OpNo));
> + return false;
> + }
> +
> + return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant,
> ExtraCode, OS);
> +}
> +
> // Force static initialization.
> extern "C" void LLVMInitializeWebAssemblyAsmPrinter() {
> RegisterAsmPrinter<WebAssemblyAsmPrinter> X(TheWebAssemblyTarget32);
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp?rev=252997&r1=252996&r2=252997&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
> (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp Thu Nov
> 12 19:42:29 2015
> @@ -56,6 +56,9 @@ public:
>
> SDNode *Select(SDNode *Node) override;
>
> + bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned
> ConstraintID,
> + std::vector<SDValue> &OutOps)
> override;
> +
> // Include the pieces autogenerated from the target description.
> #include "WebAssemblyGenDAGISel.inc"
>
> @@ -101,6 +104,22 @@ SDNode *WebAssemblyDAGToDAGISel::Select(
> return ResNode;
> }
>
> +bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand(
> + const SDValue &Op, unsigned ConstraintID, std::vector<SDValue>
> &OutOps) {
> + switch (ConstraintID) {
> + case InlineAsm::Constraint_i:
> + case InlineAsm::Constraint_m:
> + // We just support simple memory operands that just have a single
> address
> + // operand and need no special handling.
> + OutOps.push_back(Op);
> + return false;
> + default:
> + break;
> + }
> +
> + return true;
> +}
> +
> /// This pass converts a legalized DAG into a WebAssembly-specific DAG,
> ready
> /// for instruction scheduling.
> FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine &TM,
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=252997&r1=252996&r2=252997&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
> (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Thu Nov
> 12 19:42:29 2015
> @@ -211,6 +211,23 @@ WebAssemblyTargetLowering::getTargetNode
> return nullptr;
> }
>
> +std::pair<unsigned, const TargetRegisterClass *>
> +WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
> + const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
> + // First, see if this is a constraint that directly corresponds to a
> + // WebAssembly register class.
> + if (Constraint.size() == 1) {
> + switch (Constraint[0]) {
> + case 'r':
> + return std::make_pair(0U, &WebAssembly::I32RegClass);
> + default:
> + break;
> + }
> + }
> +
> + return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint,
> VT);
> +}
> +
>
> //===----------------------------------------------------------------------===//
> // WebAssembly Lowering private implementation.
>
> //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=252997&r1=252996&r2=252997&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Thu Nov 12
> 19:42:29 2015
> @@ -49,6 +49,9 @@ private:
> bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
> MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override;
> const char *getTargetNodeName(unsigned Opcode) const override;
> + std::pair<unsigned, const TargetRegisterClass *>
> + getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
> + StringRef Constraint, MVT VT) const
> override;
>
> SDValue LowerCall(CallLoweringInfo &CLI,
> SmallVectorImpl<SDValue> &InVals) const override;
>
> Added: llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll?rev=252997&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll (added)
> +++ llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll Thu Nov 12 19:42:29
> 2015
> @@ -0,0 +1,53 @@
> +; RUN: llc < %s -asm-verbose=false | FileCheck %s
> +
> +; Test basic inline assembly.
> +
> +target datalayout = "e-p:32:32-i64:64-n32:64-S128"
> +target triple = "wasm32-unknown-unknown"
> +
> +; CHECK-LABEL: foo:
> +; CHECK-NEXT: .param i32{{$}}
> +; CHECK-NEXT: .result i32{{$}}
> +; CHECK-NEXT: .local i32, i32{{$}}
> +; CHECK-NEXT: #APP{{$}}
> +; CHECK-NEXT: 1 = aaa(0){{$}}
> +; CHECK-NEXT: #NO_APP{{$}}
> +; CHECK-NEXT: return (get_local 1){{$}}
> +define i32 @foo(i32 %r) {
> +entry:
> + %0 = tail call i32 asm sideeffect "$0 = aaa($1)", "=r,r"(i32 %r) #0,
> !srcloc !0
> + ret i32 %0
> +}
> +
> +; CHECK-LABEL: bar:
> +; CHECK-NEXT: .param i32{{$}}
> +; CHECK-NEXT: .param i32{{$}}
> +; CHECK-NEXT: .local i32, i32{{$}}
> +; CHECK-NEXT: #APP{{$}}
> +; CHECK-NEXT: 1 = bbb(0){{$}}
> +; CHECK-NEXT: #NO_APP{{$}}
> +; CHECK-NEXT: return{{$}}
> +define void @bar(i32* %r, i32* %s) {
> +entry:
> + tail call void asm sideeffect "$0 = bbb($1)", "=*m,*m"(i32* %s, i32*
> %r) #0, !srcloc !1
> + ret void
> +}
> +
> +; CHECK-LABEL: imm:
> +; CHECK-NEXT: .result i32{{$}}
> +; CHECK-NEXT: .local i32{{$}}
> +; CHECK-NEXT: #APP{{$}}
> +; CHECK-NEXT: 0 = ccc(42){{$}}
> +; CHECK-NEXT: #NO_APP{{$}}
> +; CHECK-NEXT: return (get_local 0){{$}}
> +define i32 @imm() {
> +entry:
> + %0 = tail call i32 asm sideeffect "$0 = ccc($1)", "=r,i"(i32 42) #0,
> !srcloc !2
> + ret i32 %0
> +}
> +
> +attributes #0 = { nounwind }
> +
> +!0 = !{i32 47}
> +!1 = !{i32 145}
> +!2 = !{i32 231}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151116/ae3a6445/attachment.html>
More information about the llvm-commits
mailing list