[llvm] r334985 - [WebAssembly] Modified tablegen defs to have 2 parallel instuction sets.

Wouter van Oortmerssen via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 18 14:22:44 PDT 2018


Author: aardappel
Date: Mon Jun 18 14:22:44 2018
New Revision: 334985

URL: http://llvm.org/viewvc/llvm-project?rev=334985&view=rev
Log:
[WebAssembly] Modified tablegen defs to have 2 parallel instuction sets.

Summary:
One for register based, much like the existing definitions,
and one for stack based (suffix _S).

This allows us to use registers in most of LLVM (which works better),
and stack based in MC (which results in a simpler and more readable
assembler / disassembler).

Tried to keep this change as small as possible while passing tests,
follow-up commit will:
- Add reg->stack conversion in MI.
- Fix asm/disasm in MC to be stack based.
- Fix emitter to be stack based.

tests passing:
llvm-lit -v `find test -name WebAssembly`

test/CodeGen/WebAssembly
test/MC/WebAssembly
test/MC/Disassembler/WebAssembly
test/DebugInfo/WebAssembly
test/CodeGen/MIR/WebAssembly
test/tools/llvm-objdump/WebAssembly

Reviewers: dschuff, sbc100, jgravelle-google, sunfish

Subscribers: aheejin, JDevlieghere, llvm-commits

Differential Revision: https://reviews.llvm.org/D48183

Modified:
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
    llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Mon Jun 18 14:22:44 2018
@@ -109,38 +109,68 @@ namespace WebAssembly {
 inline unsigned GetDefaultP2Align(unsigned Opcode) {
   switch (Opcode) {
   case WebAssembly::LOAD8_S_I32:
+  case WebAssembly::LOAD8_S_I32_S:
   case WebAssembly::LOAD8_U_I32:
+  case WebAssembly::LOAD8_U_I32_S:
   case WebAssembly::LOAD8_S_I64:
+  case WebAssembly::LOAD8_S_I64_S:
   case WebAssembly::LOAD8_U_I64:
+  case WebAssembly::LOAD8_U_I64_S:
   case WebAssembly::ATOMIC_LOAD8_U_I32:
+  case WebAssembly::ATOMIC_LOAD8_U_I32_S:
   case WebAssembly::ATOMIC_LOAD8_U_I64:
+  case WebAssembly::ATOMIC_LOAD8_U_I64_S:
   case WebAssembly::STORE8_I32:
+  case WebAssembly::STORE8_I32_S:
   case WebAssembly::STORE8_I64:
+  case WebAssembly::STORE8_I64_S:
     return 0;
   case WebAssembly::LOAD16_S_I32:
+  case WebAssembly::LOAD16_S_I32_S:
   case WebAssembly::LOAD16_U_I32:
+  case WebAssembly::LOAD16_U_I32_S:
   case WebAssembly::LOAD16_S_I64:
+  case WebAssembly::LOAD16_S_I64_S:
   case WebAssembly::LOAD16_U_I64:
+  case WebAssembly::LOAD16_U_I64_S:
   case WebAssembly::ATOMIC_LOAD16_U_I32:
+  case WebAssembly::ATOMIC_LOAD16_U_I32_S:
   case WebAssembly::ATOMIC_LOAD16_U_I64:
+  case WebAssembly::ATOMIC_LOAD16_U_I64_S:
   case WebAssembly::STORE16_I32:
+  case WebAssembly::STORE16_I32_S:
   case WebAssembly::STORE16_I64:
+  case WebAssembly::STORE16_I64_S:
     return 1;
   case WebAssembly::LOAD_I32:
+  case WebAssembly::LOAD_I32_S:
   case WebAssembly::LOAD_F32:
+  case WebAssembly::LOAD_F32_S:
   case WebAssembly::STORE_I32:
+  case WebAssembly::STORE_I32_S:
   case WebAssembly::STORE_F32:
+  case WebAssembly::STORE_F32_S:
   case WebAssembly::LOAD32_S_I64:
+  case WebAssembly::LOAD32_S_I64_S:
   case WebAssembly::LOAD32_U_I64:
+  case WebAssembly::LOAD32_U_I64_S:
   case WebAssembly::STORE32_I64:
+  case WebAssembly::STORE32_I64_S:
   case WebAssembly::ATOMIC_LOAD_I32:
+  case WebAssembly::ATOMIC_LOAD_I32_S:
   case WebAssembly::ATOMIC_LOAD32_U_I64:
+  case WebAssembly::ATOMIC_LOAD32_U_I64_S:
     return 2;
   case WebAssembly::LOAD_I64:
+  case WebAssembly::LOAD_I64_S:
   case WebAssembly::LOAD_F64:
+  case WebAssembly::LOAD_F64_S:
   case WebAssembly::STORE_I64:
+  case WebAssembly::STORE_I64_S:
   case WebAssembly::STORE_F64:
+  case WebAssembly::STORE_F64_S:
   case WebAssembly::ATOMIC_LOAD_I64:
+  case WebAssembly::ATOMIC_LOAD_I64_S:
     return 3;
   default:
     llvm_unreachable("Only loads and stores have p2align values");

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td Mon Jun 18 14:22:44 2018
@@ -17,8 +17,8 @@
 //===----------------------------------------------------------------------===//
 
 let Defs = [ARGUMENTS] in {
-def ATOMIC_LOAD_I32 : WebAssemblyLoad<I32, "i32.atomic.load", 0xfe10>;
-def ATOMIC_LOAD_I64 : WebAssemblyLoad<I64, "i64.atomic.load", 0xfe11>;
+defm ATOMIC_LOAD_I32 : WebAssemblyLoad<I32, "i32.atomic.load", 0xfe10>;
+defm ATOMIC_LOAD_I64 : WebAssemblyLoad<I64, "i64.atomic.load", 0xfe11>;
 } // Defs = [ARGUMENTS]
 
 // Select loads with no constant offset.
@@ -56,11 +56,11 @@ def : LoadPatExternSymOffOnly<i64, atomi
 // Extending loads. Note that there are only zero-extending atomic loads, no
 // sign-extending loads.
 let Defs = [ARGUMENTS] in {
-def ATOMIC_LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load8_u", 0xfe12>;
-def ATOMIC_LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load16_u", 0xfe13>;
-def ATOMIC_LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load8_u", 0xfe14>;
-def ATOMIC_LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load16_u", 0xfe15>;
-def ATOMIC_LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load32_u", 0xfe16>;
+defm ATOMIC_LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load8_u", 0xfe12>;
+defm ATOMIC_LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load16_u", 0xfe13>;
+defm ATOMIC_LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load8_u", 0xfe14>;
+defm ATOMIC_LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load16_u", 0xfe15>;
+defm ATOMIC_LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load32_u", 0xfe16>;
 } // Defs = [ARGUMENTS]
 
 // Fragments for exending loads. These are different from regular loads because

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrCall.td Mon Jun 18 14:22:44 2018
@@ -13,57 +13,72 @@
 //===----------------------------------------------------------------------===//
 
 // TODO: addr64: These currently assume the callee address is 32-bit.
+// FIXME: add $type to first call_indirect asmstr (and maybe $flags)
 
 let Defs = [ARGUMENTS] in {
 
 // Call sequence markers. These have an immediate which represents the amount of
 // stack space to allocate or free, which is used for varargs lowering.
 let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in {
-def ADJCALLSTACKDOWN : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
-                         [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
-def ADJCALLSTACKUP : I<(outs), (ins i32imm:$amt, i32imm:$amt2),
-                       [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
+defm ADJCALLSTACKDOWN : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
+                            [(WebAssemblycallseq_start timm:$amt, timm:$amt2)]>;
+defm ADJCALLSTACKUP : NRI<(outs), (ins i32imm:$amt, i32imm:$amt2),
+                          [(WebAssemblycallseq_end timm:$amt, timm:$amt2)]>;
 } // isCodeGenOnly = 1
 
 multiclass CALL<WebAssemblyRegClass vt, string prefix> {
-  def CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
-                   [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
-                   !strconcat(prefix, "call\t$dst, $callee"),
-                   0x10>;
+  defm CALL_#vt : I<(outs vt:$dst), (ins function32_op:$callee, variable_ops),
+                    (outs), (ins function32_op:$callee),
+                    [(set vt:$dst, (WebAssemblycall1 (i32 imm:$callee)))],
+                    !strconcat(prefix, "call\t$dst, $callee"),
+                    !strconcat(prefix, "call\t$callee"),
+                    0x10>;
 
   let isCodeGenOnly = 1 in {
-    def PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
-                              [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
-                              "PSEUDO CALL INDIRECT\t$callee">;
+    defm PCALL_INDIRECT_#vt : I<(outs vt:$dst), (ins I32:$callee, variable_ops),
+                                (outs), (ins I32:$callee),
+                               [(set vt:$dst, (WebAssemblycall1 I32:$callee))],
+                               "PSEUDO CALL INDIRECT\t$callee",
+                               "PSEUDO CALL INDIRECT\t$callee">;
   } // isCodeGenOnly = 1
 
-  def CALL_INDIRECT_#vt : I<(outs vt:$dst),
-                            (ins TypeIndex:$type, i32imm:$flags, variable_ops),
-                            [],
-                            !strconcat(prefix, "call_indirect\t$dst"),
-                            0x11>;
+  defm CALL_INDIRECT_#vt : I<(outs vt:$dst),
+                             (ins TypeIndex:$type, i32imm:$flags, variable_ops),
+                             (outs), (ins TypeIndex:$type, i32imm:$flags),
+                             [],
+                             !strconcat(prefix, "call_indirect\t$dst"),
+                             !strconcat(prefix, "call_indirect\t$type"),
+                             0x11>;
 }
 
 multiclass SIMD_CALL<ValueType vt, string prefix> {
-  def CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee, variable_ops),
+  defm CALL_#vt : SIMD_I<(outs V128:$dst), (ins function32_op:$callee,
+                           variable_ops),
+                         (outs), (ins function32_op:$callee),
                          [(set (vt V128:$dst),
-                               (WebAssemblycall1 (i32 imm:$callee)))],
+                            (WebAssemblycall1 (i32 imm:$callee)))],
                          !strconcat(prefix, "call\t$dst, $callee"),
+                         !strconcat(prefix, "call\t$callee"),
                          0x10>;
 
   let isCodeGenOnly = 1 in {
-    def PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
-                                    (ins I32:$callee, variable_ops),
-                                    [(set (vt V128:$dst),
-                                          (WebAssemblycall1 I32:$callee))],
-                                    "PSEUDO CALL INDIRECT\t$callee">;
+    defm PCALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
+                                     (ins I32:$callee, variable_ops),
+                                     (outs), (ins I32:$callee),
+                                     [(set (vt V128:$dst),
+                                           (WebAssemblycall1 I32:$callee))],
+                                     "PSEUDO CALL INDIRECT\t$callee",
+                                     "PSEUDO CALL INDIRECT\t$callee">;
   } // isCodeGenOnly = 1
 
-  def CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
+  defm CALL_INDIRECT_#vt : SIMD_I<(outs V128:$dst),
                                   (ins TypeIndex:$type, i32imm:$flags,
-                                       variable_ops),
+                                        variable_ops),
+                                  (outs), (ins TypeIndex:$type, i32imm:$flags),
                                   [],
-                                  !strconcat(prefix, "call_indirect\t$dst"),
+                                  !strconcat(prefix,
+                                    "call_indirect\t$dst"),
+                                  !strconcat(prefix, "call_indirect\t$type"),
                                   0x11>;
 }
 
@@ -78,20 +93,26 @@ let Uses = [SP32, SP64], isCall = 1 in {
   defm "" : SIMD_CALL<v4i32, "i32x4.">;
   defm "" : SIMD_CALL<v4f32, "f32x4.">;
 
-  def CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
-                    [(WebAssemblycall0 (i32 imm:$callee))],
-                    "call    \t$callee", 0x10>;
+  defm CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops),
+                     (outs), (ins function32_op:$callee),
+                     [(WebAssemblycall0 (i32 imm:$callee))],
+                     "call    \t$callee", "call\t$callee", 0x10>;
 
   let isCodeGenOnly = 1 in {
-    def PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
-                      [(WebAssemblycall0 I32:$callee)],
-                      "PSEUDO CALL INDIRECT\t$callee">;
+    defm PCALL_INDIRECT_VOID : I<(outs), (ins I32:$callee, variable_ops),
+                                 (outs), (ins I32:$callee),
+                                 [(WebAssemblycall0 I32:$callee)],
+                                 "PSEUDO CALL INDIRECT\t$callee",
+                                 "PSEUDO CALL INDIRECT\t$callee">;
   } // isCodeGenOnly = 1
 
-  def CALL_INDIRECT_VOID : I<(outs),
-                             (ins TypeIndex:$type, i32imm:$flags, variable_ops),
-                             [],
-                             "call_indirect\t", 0x11>;
+  defm CALL_INDIRECT_VOID : I<(outs),
+                              (ins TypeIndex:$type, i32imm:$flags,
+                                variable_ops),
+                              (outs), (ins TypeIndex:$type, i32imm:$flags),
+                              [],
+                              "call_indirect\t", "call_indirect\t$type",
+                              0x11>;
 } // Uses = [SP32,SP64], isCall = 1
 
 } // Defs = [ARGUMENTS]

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Mon Jun 18 14:22:44 2018
@@ -16,15 +16,17 @@ let Defs = [ARGUMENTS] in {
 
 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
 // The condition operand is a boolean value which WebAssembly represents as i32.
-def BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
-              [(brcond I32:$cond, bb:$dst)],
-               "br_if   \t$dst, $cond", 0x0d>;
+defm BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond),
+               (outs), (ins bb_op:$dst),
+               [(brcond I32:$cond, bb:$dst)],
+                "br_if   \t$dst, $cond", "br_if   \t$dst", 0x0d>;
 let isCodeGenOnly = 1 in
-def BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond), []>;
+defm BR_UNLESS : I<(outs), (ins bb_op:$dst, I32:$cond),
+                   (outs), (ins bb_op:$dst), []>;
 let isBarrier = 1 in {
-def BR   : I<(outs), (ins bb_op:$dst),
-             [(br bb:$dst)],
-             "br      \t$dst", 0x0c>;
+defm BR   : NRI<(outs), (ins bb_op:$dst),
+                [(br bb:$dst)],
+                "br      \t$dst", 0x0c>;
 } // isBarrier = 1
 } // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
 
@@ -42,16 +44,30 @@ let Defs = [ARGUMENTS] in {
 // currently.
 // Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
 // Set TSFlags{1} to 1 to indicate that the immediates represent labels.
+// FIXME: this can't inherit from I<> since there is no way to inherit from a
+// multiclass and still have the let statements.
 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
-def BR_TABLE_I32 : I<(outs), (ins I32:$index, variable_ops),
-                     [(WebAssemblybr_table I32:$index)],
-                     "br_table \t$index", 0x0e> {
+def BR_TABLE_I32 : NI<(outs), (ins I32:$index, variable_ops),
+                      [(WebAssemblybr_table I32:$index)], 0,
+                      "br_table \t$index", 0x0e> {
   let TSFlags{0} = 1;
   let TSFlags{1} = 1;
 }
-def BR_TABLE_I64 : I<(outs), (ins I64:$index, variable_ops),
-                     [(WebAssemblybr_table I64:$index)],
-                     "br_table \t$index"> {
+def BR_TABLE_I32_S : NI<(outs), (ins I32:$index),
+                        [], 1,
+                        "br_table \t$index", 0x0e> {
+  let TSFlags{0} = 1;
+  let TSFlags{1} = 1;
+}
+def BR_TABLE_I64 : NI<(outs), (ins I64:$index, variable_ops),
+                      [(WebAssemblybr_table I64:$index)], 0,
+                      "br_table \t$index"> {
+  let TSFlags{0} = 1;
+  let TSFlags{1} = 1;
+}
+def BR_TABLE_I64_S : NI<(outs), (ins I64:$index),
+                        [], 1,
+                        "br_table \t$index"> {
   let TSFlags{0} = 1;
   let TSFlags{1} = 1;
 }
@@ -59,40 +75,42 @@ def BR_TABLE_I64 : I<(outs), (ins I64:$i
 
 // This is technically a control-flow instruction, since all it affects is the
 // IP.
-def NOP : I<(outs), (ins), [], "nop", 0x01>;
+defm NOP : NRI<(outs), (ins), [], "nop", 0x01>;
 
 // Placemarkers to indicate the start or end of a block or loop scope.
 // These use/clobber VALUE_STACK to prevent them from being moved into the
 // middle of an expression tree.
 let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
-def BLOCK     : I<(outs), (ins Signature:$sig), [], "block   \t$sig", 0x02>;
-def LOOP      : I<(outs), (ins Signature:$sig), [], "loop    \t$sig", 0x03>;
+defm BLOCK     : NRI<(outs), (ins Signature:$sig), [], "block   \t$sig", 0x02>;
+defm LOOP      : NRI<(outs), (ins Signature:$sig), [], "loop    \t$sig", 0x03>;
 
 // END_BLOCK, END_LOOP, and END_FUNCTION are represented with the same opcode in
 // wasm.
-def END_BLOCK : I<(outs), (ins), [], "end_block", 0x0b>;
-def END_LOOP  : I<(outs), (ins), [], "end_loop", 0x0b>;
+defm END_BLOCK : NRI<(outs), (ins), [], "end_block", 0x0b>;
+defm END_LOOP  : NRI<(outs), (ins), [], "end_loop", 0x0b>;
 let isTerminator = 1, isBarrier = 1 in
-def END_FUNCTION : I<(outs), (ins), [], "end_function", 0x0b>;
+defm END_FUNCTION : NRI<(outs), (ins), [], "end_function", 0x0b>;
 } // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
 
 multiclass RETURN<WebAssemblyRegClass vt> {
-  def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
-                     "return  \t$val", 0x0f>;
+  defm RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins),
+                      [(WebAssemblyreturn vt:$val)],
+                      "return  \t$val", "return", 0x0f>;
   // Equivalent to RETURN_#vt, for use at the end of a function when wasm
   // semantics return by falling off the end of the block.
   let isCodeGenOnly = 1 in
-  def FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), []>;
+  defm FALLTHROUGH_RETURN_#vt : I<(outs), (ins vt:$val), (outs), (ins), []>;
 }
 
 multiclass SIMD_RETURN<ValueType vt> {
-  def RETURN_#vt : SIMD_I<(outs), (ins V128:$val),
-                          [(WebAssemblyreturn (vt V128:$val))],
-                          "return  \t$val", 0x0f>;
+  defm RETURN_#vt : SIMD_I<(outs), (ins V128:$val), (outs), (ins),
+                           [(WebAssemblyreturn (vt V128:$val))],
+                           "return  \t$val", "return", 0x0f>;
   // Equivalent to RETURN_#vt, for use at the end of a function when wasm
   // semantics return by falling off the end of the block.
   let isCodeGenOnly = 1 in
-  def FALLTHROUGH_RETURN_#vt : SIMD_I<(outs), (ins V128:$val), []>;
+  defm FALLTHROUGH_RETURN_#vt : SIMD_I<(outs), (ins V128:$val), (outs), (ins),
+                                       []>;
 }
 
 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
@@ -108,14 +126,14 @@ let isReturn = 1 in {
   defm "": SIMD_RETURN<v4i32>;
   defm "": SIMD_RETURN<v4f32>;
 
-  def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return", 0x0f>;
+  defm RETURN_VOID : NRI<(outs), (ins), [(WebAssemblyreturn)], "return", 0x0f>;
 
   // This is to RETURN_VOID what FALLTHROUGH_RETURN_#vt is to RETURN_#vt.
   let isCodeGenOnly = 1 in
-  def FALLTHROUGH_RETURN_VOID : I<(outs), (ins), []>;
+  defm FALLTHROUGH_RETURN_VOID : NRI<(outs), (ins), []>;
 } // isReturn = 1
 
-def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable", 0x00>;
+defm UNREACHABLE : NRI<(outs), (ins), [(trap)], "unreachable", 0x00>;
 } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
 
 //===----------------------------------------------------------------------===//
@@ -124,31 +142,37 @@ def UNREACHABLE : I<(outs), (ins), [(tra
 
 // Throwing an exception: throw / rethrow
 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
-def THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
-                  [(int_wasm_throw imm:$tag, I32:$val)], "throw   \t$tag, $val",
-                  0x08>;
-def THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
-                  [(int_wasm_throw imm:$tag, I64:$val)], "throw   \t$tag, $val",
-                  0x08>;
-def RETHROW : I<(outs), (ins i32imm:$rel_depth), [], "rethrow \t$rel_depth",
-                0x09>;
+defm THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
+                   (outs), (ins i32imm:$tag),
+                   [(int_wasm_throw imm:$tag, I32:$val)],
+                   "throw   \t$tag, $val", "throw   \t$tag",
+                   0x08>;
+defm THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
+                   (outs), (ins i32imm:$tag),
+                   [(int_wasm_throw imm:$tag, I64:$val)],
+                   "throw   \t$tag, $val", "throw   \t$tag",
+                   0x08>;
+defm RETHROW : NRI<(outs), (ins i32imm:$rel_depth), [], "rethrow \t$rel_depth",
+                   0x09>;
 } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
 
 // Region within which an exception is caught: try / end_try
 let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
-def TRY     : I<(outs), (ins Signature:$sig), [], "try     \t$sig", 0x06>;
-def END_TRY : I<(outs), (ins), [], "end_try", 0x0b>;
+defm TRY     : NRI<(outs), (ins Signature:$sig), [], "try     \t$sig", 0x06>;
+defm END_TRY : NRI<(outs), (ins), [], "end_try", 0x0b>;
 } // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
 
 // Catching an exception: catch / catch_all
 let hasCtrlDep = 1 in {
-def CATCH_I32 : I<(outs I32:$dst), (ins i32imm:$tag),
-                  [(set I32:$dst, (int_wasm_catch imm:$tag))],
-                  "i32.catch   \t$dst, $tag", 0x07>;
-def CATCH_I64 : I<(outs I64:$dst), (ins i32imm:$tag),
-                  [(set I64:$dst, (int_wasm_catch imm:$tag))],
-                  "i64.catch   \t$dst, $tag", 0x07>;
-def CATCH_ALL : I<(outs), (ins), [], "catch_all", 0x05>;
+defm CATCH_I32 : I<(outs I32:$dst), (ins i32imm:$tag),
+                   (outs), (ins i32imm:$tag),
+                   [(set I32:$dst, (int_wasm_catch imm:$tag))],
+                   "i32.catch   \t$dst, $tag", "i32.catch   \t$tag", 0x07>;
+defm CATCH_I64 : I<(outs I64:$dst), (ins i32imm:$tag),
+                   (outs), (ins i32imm:$tag),
+                   [(set I64:$dst, (int_wasm_catch imm:$tag))],
+                   "i64.catch   \t$dst, $tag", "i64.catch   \t$tag", 0x07>;
+defm CATCH_ALL : NRI<(outs), (ins), [], "catch_all", 0x05>;
 }
 
 // Pseudo instructions: cleanupret / catchret
@@ -156,8 +180,8 @@ def CATCH_ALL : I<(outs), (ins), [], "ca
 // in X86 is necessary for computing EH scope membership.
 let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
     isCodeGenOnly = 1, isReturn = 1 in {
-  def CLEANUPRET : I<(outs), (ins), [(cleanupret)], "", 0>;
-  def CATCHRET : I<(outs), (ins bb_op:$dst, bb_op:$from),
+  defm CLEANUPRET : NRI<(outs), (ins), [(cleanupret)], "", 0>;
+  defm CATCHRET : NRI<(outs), (ins bb_op:$dst, bb_op:$from),
                    [(catchret bb:$dst, bb:$from)], "", 0>;
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrConv.td Mon Jun 18 14:22:44 2018
@@ -15,33 +15,40 @@
 
 let Defs = [ARGUMENTS] in {
 
-def I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src),
+defm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
                       [(set I32:$dst, (trunc I64:$src))],
-                      "i32.wrap/i64\t$dst, $src", 0xa7>;
+                      "i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>;
 
-def I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src),
+defm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
                           [(set I64:$dst, (sext I32:$src))],
-                          "i64.extend_s/i32\t$dst, $src", 0xac>;
-def I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src),
-                         [(set I64:$dst, (zext I32:$src))],
-                         "i64.extend_u/i32\t$dst, $src", 0xad>;
+                          "i64.extend_s/i32\t$dst, $src", "i64.extend_s/i32",
+                          0xac>;
+defm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins),
+                          [(set I64:$dst, (zext I32:$src))],
+                          "i64.extend_u/i32\t$dst, $src", "i64.extend_u/i32",
+                          0xad>;
 
 let Predicates = [HasSignExt] in {
-def I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src),
-                          [(set I32:$dst, (sext_inreg I32:$src, i8))],
-                          "i32.extend8_s\t$dst, $src", 0xc0>;
-def I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src),
-                           [(set I32:$dst, (sext_inreg I32:$src, i16))],
-                           "i32.extend16_s\t$dst, $src", 0xc1>;
-def I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src),
-                           [(set I64:$dst, (sext_inreg I64:$src, i8))],
-                           "i64.extend8_s\t$dst, $src", 0xc2>;
-def I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src),
-                           [(set I64:$dst, (sext_inreg I64:$src, i16))],
-                           "i64.extend16_s\t$dst, $src", 0xc3>;
-def I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src),
-                           [(set I64:$dst, (sext_inreg I64:$src, i32))],
-                           "i64.extend32_s\t$dst, $src", 0xc4>;
+defm I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+                           [(set I32:$dst, (sext_inreg I32:$src, i8))],
+                           "i32.extend8_s\t$dst, $src", "i32.extend8_s",
+                           0xc0>;
+defm I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+                            [(set I32:$dst, (sext_inreg I32:$src, i16))],
+                            "i32.extend16_s\t$dst, $src", "i32.extend16_s",
+                            0xc1>;
+defm I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+                            [(set I64:$dst, (sext_inreg I64:$src, i8))],
+                            "i64.extend8_s\t$dst, $src", "i64.extend8_s",
+                            0xc2>;
+defm I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+                            [(set I64:$dst, (sext_inreg I64:$src, i16))],
+                            "i64.extend16_s\t$dst, $src", "i64.extend16_s",
+                            0xc3>;
+defm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+                            [(set I64:$dst, (sext_inreg I64:$src, i32))],
+                            "i64.extend32_s\t$dst, $src", "i64.extend32_s",
+                            0xc4>;
 } // Predicates = [HasSignExt]
 
 } // defs = [ARGUMENTS]
@@ -55,131 +62,161 @@ let Defs = [ARGUMENTS] in {
 
 // Conversion from floating point to integer instructions which don't trap on
 // overflow or invalid.
-def I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src),
-                            [(set I32:$dst, (fp_to_sint F32:$src))],
-                            "i32.trunc_s:sat/f32\t$dst, $src", 0xfc00>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src),
-                            [(set I32:$dst, (fp_to_uint F32:$src))],
-                            "i32.trunc_u:sat/f32\t$dst, $src", 0xfc01>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src),
-                            [(set I64:$dst, (fp_to_sint F32:$src))],
-                            "i64.trunc_s:sat/f32\t$dst, $src", 0xfc04>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src),
-                            [(set I64:$dst, (fp_to_uint F32:$src))],
-                            "i64.trunc_u:sat/f32\t$dst, $src", 0xfc05>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src),
-                            [(set I32:$dst, (fp_to_sint F64:$src))],
-                            "i32.trunc_s:sat/f64\t$dst, $src", 0xfc02>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src),
-                            [(set I32:$dst, (fp_to_uint F64:$src))],
-                            "i32.trunc_u:sat/f64\t$dst, $src", 0xfc03>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src),
-                            [(set I64:$dst, (fp_to_sint F64:$src))],
-                            "i64.trunc_s:sat/f64\t$dst, $src", 0xfc06>,
-                            Requires<[HasNontrappingFPToInt]>;
-def I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src),
-                            [(set I64:$dst, (fp_to_uint F64:$src))],
-                            "i64.trunc_u:sat/f64\t$dst, $src", 0xfc07>,
-                            Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                             [(set I32:$dst, (fp_to_sint F32:$src))],
+                             "i32.trunc_s:sat/f32\t$dst, $src",
+                             "i32.trunc_s:sat/f32", 0xfc00>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                             [(set I32:$dst, (fp_to_uint F32:$src))],
+                             "i32.trunc_u:sat/f32\t$dst, $src",
+                             "i32.trunc_u:sat/f32", 0xfc01>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                             [(set I64:$dst, (fp_to_sint F32:$src))],
+                             "i64.trunc_s:sat/f32\t$dst, $src",
+                             "i64.trunc_s:sat/f32", 0xfc04>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                             [(set I64:$dst, (fp_to_uint F32:$src))],
+                             "i64.trunc_u:sat/f32\t$dst, $src",
+                             "i64.trunc_u:sat/f32", 0xfc05>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                             [(set I32:$dst, (fp_to_sint F64:$src))],
+                             "i32.trunc_s:sat/f64\t$dst, $src",
+                             "i32.trunc_s:sat/f64", 0xfc02>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                             [(set I32:$dst, (fp_to_uint F64:$src))],
+                             "i32.trunc_u:sat/f64\t$dst, $src",
+                             "i32.trunc_u:sat/f64", 0xfc03>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                             [(set I64:$dst, (fp_to_sint F64:$src))],
+                             "i64.trunc_s:sat/f64\t$dst, $src",
+                             "i64.trunc_s:sat/f64", 0xfc06>,
+                             Requires<[HasNontrappingFPToInt]>;
+defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                             [(set I64:$dst, (fp_to_uint F64:$src))],
+                             "i64.trunc_u:sat/f64\t$dst, $src",
+                             "i64.trunc_u:sat/f64", 0xfc07>,
+                             Requires<[HasNontrappingFPToInt]>;
 
 // Conversion from floating point to integer pseudo-instructions which don't
 // trap on overflow or invalid.
 let usesCustomInserter = 1, isCodeGenOnly = 1 in {
-def FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src),
-                        [(set I32:$dst, (fp_to_sint F32:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src),
-                        [(set I32:$dst, (fp_to_uint F32:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src),
-                        [(set I64:$dst, (fp_to_sint F32:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src),
-                        [(set I64:$dst, (fp_to_uint F32:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src),
-                        [(set I32:$dst, (fp_to_sint F64:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src),
-                        [(set I32:$dst, (fp_to_uint F64:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src),
-                        [(set I64:$dst, (fp_to_sint F64:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
-def FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src),
-                        [(set I64:$dst, (fp_to_uint F64:$src))], "", 0>,
-                        Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                            [(set I32:$dst, (fp_to_sint F32:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                            [(set I32:$dst, (fp_to_uint F32:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                            [(set I64:$dst, (fp_to_sint F32:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                            [(set I64:$dst, (fp_to_uint F32:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                            [(set I32:$dst, (fp_to_sint F64:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                            [(set I32:$dst, (fp_to_uint F64:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                            [(set I64:$dst, (fp_to_sint F64:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
+defm FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                            [(set I64:$dst, (fp_to_uint F64:$src))], "", "", 0>,
+                            Requires<[NotHasNontrappingFPToInt]>;
 } // usesCustomInserter, isCodeGenOnly = 1
 
 // Conversion from floating point to integer traps on overflow and invalid.
 let hasSideEffects = 1 in {
-def I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src),
-                        [], "i32.trunc_s/f32\t$dst, $src", 0xa8>;
-def I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src),
-                        [], "i32.trunc_u/f32\t$dst, $src", 0xa9>;
-def I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src),
-                        [], "i64.trunc_s/f32\t$dst, $src", 0xae>;
-def I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src),
-                        [], "i64.trunc_u/f32\t$dst, $src", 0xaf>;
-def I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src),
-                        [], "i32.trunc_s/f64\t$dst, $src", 0xaa>;
-def I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src),
-                        [], "i32.trunc_u/f64\t$dst, $src", 0xab>;
-def I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src),
-                        [], "i64.trunc_s/f64\t$dst, $src", 0xb0>;
-def I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src),
-                        [], "i64.trunc_u/f64\t$dst, $src", 0xb1>;
+defm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                         [], "i32.trunc_s/f32\t$dst, $src", "i32.trunc_s/f32",
+                         0xa8>;
+defm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                         [], "i32.trunc_u/f32\t$dst, $src", "i32.trunc_u/f32",
+                         0xa9>;
+defm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                         [], "i64.trunc_s/f32\t$dst, $src", "i64.trunc_s/f32",
+                         0xae>;
+defm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins),
+                         [], "i64.trunc_u/f32\t$dst, $src", "i64.trunc_u/f32",
+                         0xaf>;
+defm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                         [], "i32.trunc_s/f64\t$dst, $src", "i32.trunc_s/f64",
+                         0xaa>;
+defm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins),
+                         [], "i32.trunc_u/f64\t$dst, $src", "i32.trunc_u/f64",
+                         0xab>;
+defm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                         [], "i64.trunc_s/f64\t$dst, $src", "i64.trunc_s/f64",
+                         0xb0>;
+defm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                         [], "i64.trunc_u/f64\t$dst, $src", "i64.trunc_u/f64",
+                         0xb1>;
 } // hasSideEffects = 1
 
-def F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src),
-                          [(set F32:$dst, (sint_to_fp I32:$src))],
-                          "f32.convert_s/i32\t$dst, $src", 0xb2>;
-def F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src),
-                          [(set F32:$dst, (uint_to_fp I32:$src))],
-                          "f32.convert_u/i32\t$dst, $src", 0xb3>;
-def F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src),
-                          [(set F64:$dst, (sint_to_fp I32:$src))],
-                          "f64.convert_s/i32\t$dst, $src", 0xb7>;
-def F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src),
-                          [(set F64:$dst, (uint_to_fp I32:$src))],
-                          "f64.convert_u/i32\t$dst, $src", 0xb8>;
-def F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src),
-                          [(set F32:$dst, (sint_to_fp I64:$src))],
-                          "f32.convert_s/i64\t$dst, $src", 0xb4>;
-def F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src),
-                          [(set F32:$dst, (uint_to_fp I64:$src))],
-                          "f32.convert_u/i64\t$dst, $src", 0xb5>;
-def F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src),
-                          [(set F64:$dst, (sint_to_fp I64:$src))],
-                          "f64.convert_s/i64\t$dst, $src", 0xb9>;
-def F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src),
-                          [(set F64:$dst, (uint_to_fp I64:$src))],
-                          "f64.convert_u/i64\t$dst, $src", 0xba>;
-
-def F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src),
-                        [(set F64:$dst, (fpextend F32:$src))],
-                        "f64.promote/f32\t$dst, $src", 0xbb>;
-def F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src),
-                       [(set F32:$dst, (fpround F64:$src))],
-                       "f32.demote/f64\t$dst, $src", 0xb6>;
-
-def I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src),
-                            [(set I32:$dst, (bitconvert F32:$src))],
-                            "i32.reinterpret/f32\t$dst, $src", 0xbc>;
-def F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src),
-                            [(set F32:$dst, (bitconvert I32:$src))],
-                            "f32.reinterpret/i32\t$dst, $src", 0xbe>;
-def I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src),
-                            [(set I64:$dst, (bitconvert F64:$src))],
-                            "i64.reinterpret/f64\t$dst, $src", 0xbd>;
-def F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src),
-                            [(set F64:$dst, (bitconvert I64:$src))],
-                            "f64.reinterpret/i64\t$dst, $src", 0xbf>;
+defm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+                           [(set F32:$dst, (sint_to_fp I32:$src))],
+                           "f32.convert_s/i32\t$dst, $src", "f32.convert_s/i32",
+                           0xb2>;
+defm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+                           [(set F32:$dst, (uint_to_fp I32:$src))],
+                           "f32.convert_u/i32\t$dst, $src", "f32.convert_u/i32",
+                           0xb3>;
+defm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
+                           [(set F64:$dst, (sint_to_fp I32:$src))],
+                           "f64.convert_s/i32\t$dst, $src", "f64.convert_s/i32",
+                           0xb7>;
+defm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins),
+                           [(set F64:$dst, (uint_to_fp I32:$src))],
+                           "f64.convert_u/i32\t$dst, $src", "f64.convert_u/i32",
+                           0xb8>;
+defm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
+                           [(set F32:$dst, (sint_to_fp I64:$src))],
+                           "f32.convert_s/i64\t$dst, $src", "f32.convert_s/i64",
+                           0xb4>;
+defm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins),
+                           [(set F32:$dst, (uint_to_fp I64:$src))],
+                           "f32.convert_u/i64\t$dst, $src", "f32.convert_u/i64",
+                           0xb5>;
+defm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
+                           [(set F64:$dst, (sint_to_fp I64:$src))],
+                           "f64.convert_s/i64\t$dst, $src", "f64.convert_s/i64",
+                           0xb9>;
+defm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
+                           [(set F64:$dst, (uint_to_fp I64:$src))],
+                           "f64.convert_u/i64\t$dst, $src", "f64.convert_u/i64",
+                           0xba>;
+
+defm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins),
+                         [(set F64:$dst, (fpextend F32:$src))],
+                         "f64.promote/f32\t$dst, $src", "f64.promote/f32",
+                         0xbb>;
+defm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins),
+                        [(set F32:$dst, (fpround F64:$src))],
+                        "f32.demote/f64\t$dst, $src", "f32.demote/f64",
+                        0xb6>;
+
+defm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins),
+                             [(set I32:$dst, (bitconvert F32:$src))],
+                             "i32.reinterpret/f32\t$dst, $src",
+                             "i32.reinterpret/f32", 0xbc>;
+defm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins),
+                             [(set F32:$dst, (bitconvert I32:$src))],
+                             "f32.reinterpret/i32\t$dst, $src",
+                             "f32.reinterpret/i32", 0xbe>;
+defm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins),
+                             [(set I64:$dst, (bitconvert F64:$src))],
+                             "i64.reinterpret/f64\t$dst, $src",
+                             "i64.reinterpret/f64", 0xbd>;
+defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins),
+                             [(set F64:$dst, (bitconvert I64:$src))],
+                             "f64.reinterpret/i64\t$dst, $src",
+                             "f64.reinterpret/i64", 0xbf>;
 
 } // Defs = [ARGUMENTS]

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td Mon Jun 18 14:22:44 2018
@@ -14,12 +14,14 @@
 
 let Defs = [ARGUMENTS] in {
 
-def SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
-                          (ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
-                          [(set EXCEPT_REF:$dst,
-                           (select I32:$cond, EXCEPT_REF:$lhs,
-                            EXCEPT_REF:$rhs))],
-                          "except_ref.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
+defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst),
+                           (ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond),
+                           (outs), (ins),
+                           [(set EXCEPT_REF:$dst,
+                            (select I32:$cond, EXCEPT_REF:$lhs,
+                             EXCEPT_REF:$rhs))],
+                           "except_ref.select\t$dst, $lhs, $rhs, $cond",
+                           "except_ref.select", 0x1b>;
 
 } // Defs = [ARGUMENTS]
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td Mon Jun 18 14:22:44 2018
@@ -77,12 +77,14 @@ def : Pat<(setge f64:$lhs, f64:$rhs), (G
 
 let Defs = [ARGUMENTS] in {
 
-def SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond),
-                   [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
-                   "f32.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
-def SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond),
-                   [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
-                   "f64.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
+defm SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond),
+                    (outs), (ins),
+                    [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
+                    "f32.select\t$dst, $lhs, $rhs, $cond", "f32.select", 0x1b>;
+defm SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond),
+                    (outs), (ins),
+                    [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
+                    "f64.select\t$dst, $lhs, $rhs, $cond", "f64.select", 0x1b>;
 
 } // Defs = [ARGUMENTS]
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Mon Jun 18 14:22:44 2018
@@ -13,94 +13,155 @@
 //===----------------------------------------------------------------------===//
 
 // WebAssembly Instruction Format.
-class WebAssemblyInst<bits<32> inst, string asmstr> : Instruction {
+// We instantiate 2 of these for every actual instruction (register based
+// and stack based), see below.
+class WebAssemblyInst<bits<32> inst, string asmstr, bit stack> : Instruction {
   field bits<32> Inst = inst; // Instruction encoding.
+  field bit StackBased = stack;
   let Namespace   = "WebAssembly";
   let Pattern     = [];
   let AsmString   = asmstr;
 }
 
-// Normal instructions.
-class I<dag oops, dag iops, list<dag> pattern, string asmstr = "", bits<32> inst = -1>
-    : WebAssemblyInst<inst, asmstr> {
+// Normal instructions. Default instantiation of a WebAssemblyInst.
+class NI<dag oops, dag iops, list<dag> pattern, bit stack, string asmstr = "",
+         bits<32> inst = -1>
+    : WebAssemblyInst<inst, asmstr, stack> {
   dag OutOperandList = oops;
   dag InOperandList  = iops;
   let Pattern        = pattern;
 }
 
-class SIMD_I<dag oops, dag iops, list<dag> pattern,
-             string asmstr = "", bits<32> inst = -1>
-    : I<oops, iops, pattern, asmstr, inst>, Requires<[HasSIMD128]>;
-
-class ATOMIC_I<dag oops, dag iops, list<dag> pattern,
-               string asmstr = "", bits<32> inst = -1>
-    : I<oops, iops, pattern, asmstr, inst>, Requires<[HasAtomics]>;
+// Generates both register and stack based versions of one actual instruction.
+// We have 2 sets of operands (oops & iops) for the register and stack
+// based version of this instruction, as well as the corresponding asmstr.
+// The register versions have virtual-register operands which correspond to wasm
+// locals or stack locations. Each use and def of the register corresponds to an
+// implicit get_local / set_local or access of stack operands in wasm. These
+// instructions are used for ISel and all MI passes. The stack versions of the
+// instructions do not have register operands (they implicitly operate on the
+// stack), and get_locals and set_locals are explicit. The register instructions
+// are converted to their corresponding stack instructions before lowering to
+// MC.
+// Every instruction should want to be based on this multi-class to guarantee
+// there is always an equivalent pair of instructions.
+multiclass I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+             list<dag> pattern_r, string asmstr_r = "", string asmstr_s = "",
+             bits<32> inst = -1> {
+  def "" : NI<oops_r, iops_r, pattern_r, 0, asmstr_r, inst>;
+  def _S : NI<oops_s, iops_s, [], 1, asmstr_s, inst>;
+}
+
+// For instructions that have no register ops, so both sets are the same.
+multiclass NRI<dag oops, dag iops, list<dag> pattern, string asmstr = "",
+               bits<32> inst = -1> {
+  defm "": I<oops, iops, oops, iops, pattern, asmstr, asmstr, inst>;
+}
+
+multiclass SIMD_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+                  list<dag> pattern_r, string asmstr_r = "",
+                  string asmstr_s = "", bits<32> inst = -1> {
+  defm "" : I<oops_r, iops_r, oops_s, iops_s, pattern_r, asmstr_r, asmstr_s,
+              inst>,
+            Requires<[HasSIMD128]>;
+}
+
+multiclass ATOMIC_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
+                    list<dag> pattern_r, string asmstr_r = "",
+                    string asmstr_s = "", bits<32> inst = -1> {
+  defm "" : I<oops_r, iops_r, oops_s, iops_s, pattern_r, asmstr_r, asmstr_s,
+              inst>,
+            Requires<[HasAtomics]>;
+}
 
 // Unary and binary instructions, for the local types that WebAssembly supports.
-multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst, bits<32> i64Inst> {
-  def _I32 : I<(outs I32:$dst), (ins I32:$src),
-               [(set I32:$dst, (node I32:$src))],
-               !strconcat("i32.", !strconcat(name, "\t$dst, $src")), i32Inst>;
-  def _I64 : I<(outs I64:$dst), (ins I64:$src),
-               [(set I64:$dst, (node I64:$src))],
-               !strconcat("i64.", !strconcat(name, "\t$dst, $src")), i64Inst>;
-}
-multiclass BinaryInt<SDNode node, string name, bits<32> i32Inst, bits<32> i64Inst> {
-  def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
-               [(set I32:$dst, (node I32:$lhs, I32:$rhs))],
-               !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")), i32Inst>;
-  def _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs),
-               [(set I64:$dst, (node I64:$lhs, I64:$rhs))],
-               !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")), i64Inst>;
-}
-multiclass UnaryFP<SDNode node, string name, bits<32> f32Inst, bits<32> f64Inst> {
-  def _F32 : I<(outs F32:$dst), (ins F32:$src),
-               [(set F32:$dst, (node F32:$src))],
-               !strconcat("f32.", !strconcat(name, "\t$dst, $src")), f32Inst>;
-  def _F64 : I<(outs F64:$dst), (ins F64:$src),
-               [(set F64:$dst, (node F64:$src))],
-               !strconcat("f64.", !strconcat(name, "\t$dst, $src")), f64Inst>;
-}
-multiclass BinaryFP<SDNode node, string name, bits<32> f32Inst, bits<32> f64Inst> {
-  def _F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs),
-               [(set F32:$dst, (node F32:$lhs, F32:$rhs))],
-               !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")), f32Inst>;
-  def _F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs),
-               [(set F64:$dst, (node F64:$lhs, F64:$rhs))],
-               !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")), f64Inst>;
+multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst,
+                    bits<32> i64Inst> {
+  defm _I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+                [(set I32:$dst, (node I32:$src))],
+                !strconcat("i32.", !strconcat(name, "\t$dst, $src")),
+                !strconcat("i32.", name), i32Inst>;
+  defm _I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins),
+                [(set I64:$dst, (node I64:$src))],
+                !strconcat("i64.", !strconcat(name, "\t$dst, $src")),
+                !strconcat("i64.", name), i64Inst>;
+}
+multiclass BinaryInt<SDNode node, string name, bits<32> i32Inst,
+                     bits<32> i64Inst> {
+  defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins),
+                [(set I32:$dst, (node I32:$lhs, I32:$rhs))],
+                !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("i32.", name), i32Inst>;
+  defm _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins),
+                [(set I64:$dst, (node I64:$lhs, I64:$rhs))],
+                !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("i64.", name), i64Inst>;
+}
+multiclass UnaryFP<SDNode node, string name, bits<32> f32Inst,
+                   bits<32> f64Inst> {
+  defm _F32 : I<(outs F32:$dst), (ins F32:$src), (outs), (ins),
+                [(set F32:$dst, (node F32:$src))],
+                !strconcat("f32.", !strconcat(name, "\t$dst, $src")),
+                !strconcat("f32.", name), f32Inst>;
+  defm _F64 : I<(outs F64:$dst), (ins F64:$src), (outs), (ins),
+                [(set F64:$dst, (node F64:$src))],
+                !strconcat("f64.", !strconcat(name, "\t$dst, $src")),
+                !strconcat("f64.", name), f64Inst>;
+}
+multiclass BinaryFP<SDNode node, string name, bits<32> f32Inst,
+                    bits<32> f64Inst> {
+  defm _F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs), (outs), (ins),
+                [(set F32:$dst, (node F32:$lhs, F32:$rhs))],
+                !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("f32.", name), f32Inst>;
+  defm _F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs), (outs), (ins),
+                [(set F64:$dst, (node F64:$lhs, F64:$rhs))],
+                !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("f64.", name), f64Inst>;
 }
 multiclass SIMDBinary<SDNode node, SDNode fnode, string name> {
-  def _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
-                      [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))],
-                      !strconcat("i8x16.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
-  def _I16x8 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
-                      [(set (v8i16 V128:$dst), (node V128:$lhs, V128:$rhs))],
-                      !strconcat("i16x8.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
-  def _I32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
-                      [(set (v4i32 V128:$dst), (node V128:$lhs, V128:$rhs))],
-                      !strconcat("i32x4.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
-  def _F32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
-                      [(set (v4f32 V128:$dst), (fnode V128:$lhs, V128:$rhs))],
-                      !strconcat("f32x4.", !strconcat(name, "\t$dst, $lhs, $rhs"))>;
-
+  defm _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+                       (outs), (ins),
+                       [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))],
+                       !strconcat("i8x16.",
+                         !strconcat(name, "\t$dst, $lhs, $rhs")),
+                       !strconcat("i8x16.", name)>;
+  defm _I16x8 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+                       (outs), (ins),
+                       [(set (v8i16 V128:$dst), (node V128:$lhs, V128:$rhs))],
+                       !strconcat("i16x8.",
+                         !strconcat(name, "\t$dst, $lhs, $rhs")),
+                       !strconcat("i16x8.", name)>;
+  defm _I32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+                       (outs), (ins),
+                       [(set (v4i32 V128:$dst), (node V128:$lhs, V128:$rhs))],
+                       !strconcat("i32x4.",
+                         !strconcat(name, "\t$dst, $lhs, $rhs")),
+                       !strconcat("i32x4.", name)>;
+  defm _F32x4 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs),
+                       (outs), (ins),
+                       [(set (v4f32 V128:$dst), (fnode V128:$lhs, V128:$rhs))],
+                       !strconcat("f32x4.",
+                         !strconcat(name, "\t$dst, $lhs, $rhs")),
+                       !strconcat("f32x4.", name)>;
 }
 multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32> i64Inst> {
-  def _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs),
-               [(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))],
-               !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
-               i32Inst>;
-  def _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs),
-               [(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))],
-               !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
-               i64Inst>;
+  defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins),
+                [(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))],
+                !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("i32.", name), i32Inst>;
+  defm _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins),
+                [(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))],
+                !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("i64.", name), i64Inst>;
 }
 multiclass ComparisonFP<CondCode cond, string name, bits<32> f32Inst, bits<32> f64Inst> {
-  def _F32 : I<(outs I32:$dst), (ins F32:$lhs, F32:$rhs),
-               [(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))],
-               !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
-               f32Inst>;
-  def _F64 : I<(outs I32:$dst), (ins F64:$lhs, F64:$rhs),
-               [(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))],
-               !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
-               f64Inst>;
+  defm _F32 : I<(outs I32:$dst), (ins F32:$lhs, F32:$rhs), (outs), (ins),
+                [(set I32:$dst, (setcc F32:$lhs, F32:$rhs, cond))],
+                !strconcat("f32.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("f32.", name), f32Inst>;
+  defm  _F64 : I<(outs I32:$dst), (ins F64:$lhs, F64:$rhs), (outs), (ins),
+                [(set I32:$dst, (setcc F64:$lhs, F64:$rhs, cond))],
+                !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")),
+                !strconcat("f64.", name), f64Inst>;
 }

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Mon Jun 18 14:22:44 2018
@@ -153,13 +153,15 @@ include "WebAssemblyInstrFormats.td"
 
 multiclass ARGUMENT<WebAssemblyRegClass vt> {
   let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
-  def ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
-                       [(set vt:$res, (WebAssemblyargument timm:$argno))]>;
+  defm ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno),
+                        (outs), (ins i32imm:$argno),
+                        [(set vt:$res, (WebAssemblyargument timm:$argno))]>;
 }
 multiclass SIMD_ARGUMENT<ValueType vt> {
   let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in
-  def ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno),
-                            [(set (vt V128:$res),
+  defm ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno),
+                             (outs), (ins i32imm:$argno),
+                             [(set (vt V128:$res),
                                   (WebAssemblyargument timm:$argno))]>;
 }
 defm "": ARGUMENT<I32>;
@@ -184,47 +186,56 @@ let hasSideEffects = 0 in {
   // and set_local. COPYs are eliminated (and replaced with
   // get_local/set_local) in the ExplicitLocals pass.
   let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
-  def COPY_#vt : I<(outs vt:$res), (ins vt:$src), [], "copy_local\t$res, $src">;
+  defm COPY_#vt : I<(outs vt:$res), (ins vt:$src), (outs), (ins), [],
+                    "copy_local\t$res, $src", "copy_local">;
 
   // TEE is similar to COPY, but writes two copies of its result. Typically
   // this would be used to stackify one result and write the other result to a
   // local.
   let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
-  def TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [],
-                  "tee_local\t$res, $also, $src">;
+  defm TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), (outs), (ins), [],
+                   "tee_local\t$res, $also, $src", "tee_local">;
 
   // This is the actual get_local instruction in wasm. These are made explicit
   // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm
   // local, which is a side effect not otherwise modeled in LLVM.
   let mayLoad = 1, isAsCheapAsAMove = 1 in
-  def GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local), [],
-                        "get_local\t$res, $local", 0x20>;
+  defm GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local),
+                         (outs), (ins local_op:$local), [],
+                         "get_local\t$res, $local", "get_local\t$local", 0x20>;
 
   // This is the actual set_local instruction in wasm. These are made explicit
   // by the ExplicitLocals pass. It has mayStore because it writes to a wasm
   // local, which is a side effect not otherwise modeled in LLVM.
   let mayStore = 1, isAsCheapAsAMove = 1 in
-  def SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src), [],
-                        "set_local\t$local, $src", 0x21>;
+  defm SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src),
+                         (outs), (ins local_op:$local), [],
+                         "set_local\t$local, $src", "set_local\t$local", 0x21>;
 
   // This is the actual tee_local instruction in wasm. TEEs are turned into
   // TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason
   // as SET_LOCAL.
   let mayStore = 1, isAsCheapAsAMove = 1 in
-  def TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), [],
-                         "tee_local\t$res, $local, $src", 0x22>;
+  defm TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src),
+                         (outs), (ins local_op:$local), [],
+                         "tee_local\t$res, $local, $src", "tee_local\t$local",
+                         0x22>;
 
   // Unused values must be dropped in some contexts.
-  def DROP_#vt : I<(outs), (ins vt:$src), [],
-                   "drop\t$src", 0x1a>;
+  defm DROP_#vt : I<(outs), (ins vt:$src), (outs), (ins), [],
+                    "drop\t$src", "drop", 0x1a>;
 
   let mayLoad = 1 in
-  def GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local), [],
-                         "get_global\t$res, $local", 0x23>;
+  defm GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local),
+                          (outs), (ins global_op:$local), [],
+                          "get_global\t$res, $local", "get_global\t$local",
+                          0x23>;
 
   let mayStore = 1 in
-  def SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src), [],
-                         "set_global\t$local, $src", 0x24>;
+  defm SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src),
+                          (outs), (ins global_op:$local), [],
+                          "set_global\t$local, $src", "set_global\t$local",
+                          0x24>;
 
 } // hasSideEffects = 0
 }
@@ -236,18 +247,22 @@ defm "" : LOCAL<V128>, Requires<[HasSIMD
 defm "" : LOCAL<EXCEPT_REF>, Requires<[HasExceptionHandling]>;
 
 let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
-def CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
-                  [(set I32:$res, imm:$imm)],
-                  "i32.const\t$res, $imm", 0x41>;
-def CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
-                  [(set I64:$res, imm:$imm)],
-                  "i64.const\t$res, $imm", 0x42>;
-def CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
-                  [(set F32:$res, fpimm:$imm)],
-                  "f32.const\t$res, $imm", 0x43>;
-def CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
-                  [(set F64:$res, fpimm:$imm)],
-                  "f64.const\t$res, $imm", 0x44>;
+defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
+                   (outs), (ins i32imm_op:$imm),
+                   [(set I32:$res, imm:$imm)],
+                   "i32.const\t$res, $imm", "i32.const\t$imm", 0x41>;
+defm CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
+                   (outs), (ins i64imm_op:$imm),
+                   [(set I64:$res, imm:$imm)],
+                   "i64.const\t$res, $imm", "i64.const\t$imm", 0x42>;
+defm CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
+                   (outs), (ins f32imm_op:$imm),
+                   [(set F32:$res, fpimm:$imm)],
+                   "f32.const\t$res, $imm", "f32.const\t$imm", 0x43>;
+defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
+                   (outs), (ins f64imm_op:$imm),
+                   [(set F64:$res, fpimm:$imm)],
+                   "f64.const\t$res, $imm", "f64.const\t$imm", 0x44>;
 } // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1
 
 } // Defs = [ARGUMENTS]

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td Mon Jun 18 14:22:44 2018
@@ -56,12 +56,12 @@ defm CLZ : UnaryInt<ctlz, "clz ", 0x67,
 defm CTZ : UnaryInt<cttz, "ctz ", 0x68, 0x7a>;
 defm POPCNT : UnaryInt<ctpop, "popcnt", 0x69, 0x7b>;
 
-def EQZ_I32 : I<(outs I32:$dst), (ins I32:$src),
-                [(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
-                "i32.eqz \t$dst, $src", 0x45>;
-def EQZ_I64 : I<(outs I32:$dst), (ins I64:$src),
-                [(set I32:$dst, (setcc I64:$src, 0, SETEQ))],
-                "i64.eqz \t$dst, $src", 0x50>;
+defm EQZ_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins),
+                 [(set I32:$dst, (setcc I32:$src, 0, SETEQ))],
+                 "i32.eqz \t$dst, $src", "i32.eqz", 0x45>;
+defm EQZ_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins),
+                 [(set I32:$dst, (setcc I64:$src, 0, SETEQ))],
+                 "i64.eqz \t$dst, $src", "i64.eqz", 0x50>;
 
 } // Defs = [ARGUMENTS]
 
@@ -73,12 +73,14 @@ def : Pat<(rotr I64:$lhs, (and I64:$rhs,
 
 let Defs = [ARGUMENTS] in {
 
-def SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
-                   [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
-                   "i32.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
-def SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond),
-                   [(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))],
-                   "i64.select\t$dst, $lhs, $rhs, $cond", 0x1b>;
+defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond),
+                    (outs), (ins),
+                    [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))],
+                    "i32.select\t$dst, $lhs, $rhs, $cond", "i32.select", 0x1b>;
+defm SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond),
+                    (outs), (ins),
+                    [(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))],
+                    "i64.select\t$dst, $lhs, $rhs, $cond", "i64.select", 0x1b>;
 
 } // Defs = [ARGUMENTS]
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrMemory.td Mon Jun 18 14:22:44 2018
@@ -56,23 +56,26 @@ def regPlusGA : PatFrag<(ops node:$addr,
 let Defs = [ARGUMENTS] in {
 
 // Defines atomic and non-atomic loads, regular and extending.
-class WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> :
-  I<(outs rc:$dst),
-    (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
-    [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), Opcode>;
+multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
+  defm "": I<(outs rc:$dst),
+             (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
+             (outs), (ins P2Align:$p2align, offset32_op:$off),
+             [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
+             !strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
+}
 
 // Basic load.
 // FIXME: When we can break syntax compatibility, reorder the fields in the
 // asmstrings to match the binary encoding.
-def LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
-def LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
-def LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
-def LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
+defm LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
+defm LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
+defm LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
+defm LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
 
 } // Defs = [ARGUMENTS]
 
 // Select loads with no constant offset.
-class LoadPatNoOffset<ValueType ty, PatFrag node, I inst> :
+class LoadPatNoOffset<ValueType ty, PatFrag node, NI inst> :
   Pat<(ty (node I32:$addr)), (inst 0, 0, $addr)>;
 
 def : LoadPatNoOffset<i32, load, LOAD_I32>;
@@ -84,7 +87,7 @@ def : LoadPatNoOffset<f64, load, LOAD_F6
 // Select loads with a constant offset.
 
 // Pattern with address + immediate offset
-class LoadPatImmOff<ValueType ty, PatFrag loadkind, PatFrag operand, I inst> :
+class LoadPatImmOff<ValueType ty, PatFrag loadkind, PatFrag operand, NI inst> :
   Pat<(ty (loadkind (operand I32:$addr, imm:$off))),
       (inst 0, imm:$off, $addr)>;
 
@@ -97,7 +100,7 @@ def : LoadPatImmOff<i64, load, or_is_add
 def : LoadPatImmOff<f32, load, or_is_add, LOAD_F32>;
 def : LoadPatImmOff<f64, load, or_is_add, LOAD_F64>;
 
-class LoadPatGlobalAddr<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatGlobalAddr<ValueType ty, PatFrag loadkind, NI inst> :
   Pat<(ty (loadkind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))),
       (inst 0, tglobaladdr:$off, $addr)>;
 
@@ -106,7 +109,7 @@ def : LoadPatGlobalAddr<i64, load, LOAD_
 def : LoadPatGlobalAddr<f32, load, LOAD_F32>;
 def : LoadPatGlobalAddr<f64, load, LOAD_F64>;
 
-class LoadPatExternalSym<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatExternalSym<ValueType ty, PatFrag loadkind, NI inst> :
   Pat<(ty (loadkind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
       (inst 0, texternalsym:$off, $addr)>;
 def : LoadPatExternalSym<i32, load, LOAD_I32>;
@@ -116,7 +119,7 @@ def : LoadPatExternalSym<f64, load, LOAD
 
 
 // Select loads with just a constant offset.
-class LoadPatOffsetOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatOffsetOnly<ValueType ty, PatFrag loadkind, NI inst> :
   Pat<(ty (loadkind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>;
 
 def : LoadPatOffsetOnly<i32, load, LOAD_I32>;
@@ -124,7 +127,7 @@ def : LoadPatOffsetOnly<i64, load, LOAD_
 def : LoadPatOffsetOnly<f32, load, LOAD_F32>;
 def : LoadPatOffsetOnly<f64, load, LOAD_F64>;
 
-class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag loadkind, NI inst> :
   Pat<(ty (loadkind (WebAssemblywrapper tglobaladdr:$off))),
       (inst 0, tglobaladdr:$off, (CONST_I32 0))>;
 
@@ -133,7 +136,7 @@ def : LoadPatGlobalAddrOffOnly<i64, load
 def : LoadPatGlobalAddrOffOnly<f32, load, LOAD_F32>;
 def : LoadPatGlobalAddrOffOnly<f64, load, LOAD_F64>;
 
-class LoadPatExternSymOffOnly<ValueType ty, PatFrag loadkind, I inst> :
+class LoadPatExternSymOffOnly<ValueType ty, PatFrag loadkind, NI inst> :
   Pat<(ty (loadkind (WebAssemblywrapper texternalsym:$off))),
       (inst 0, texternalsym:$off, (CONST_I32 0))>;
 def : LoadPatExternSymOffOnly<i32, load, LOAD_I32>;
@@ -144,16 +147,16 @@ def : LoadPatExternSymOffOnly<f64, load,
 let Defs = [ARGUMENTS] in {
 
 // Extending load.
-def LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
-def LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
-def LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
-def LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
-def LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
-def LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
-def LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
-def LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>;
-def LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
-def LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
+defm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
+defm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
+defm LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
+defm LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
+defm LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
+defm LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
+defm LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
+defm LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>;
+defm LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
+defm LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
 
 } // Defs = [ARGUMENTS]
 
@@ -304,20 +307,25 @@ def : LoadPatExternSymOffOnly<i64, extlo
 let Defs = [ARGUMENTS] in {
 
 // Defines atomic and non-atomic stores, regular and truncating
-class WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> :
- I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), [],
-   !strconcat(Name, "\t${off}(${addr})${p2align}, $val"), Opcode>;
+multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
+  defm "" : I<(outs),
+              (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
+              (outs),
+              (ins P2Align:$p2align, offset32_op:$off), [],
+              !strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
+              !strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
+}
 // Basic store.
 // Note: WebAssembly inverts SelectionDAG's usual operand order.
-def STORE_I32  : WebAssemblyStore<I32, "i32.store", 0x36>;
-def STORE_I64  : WebAssemblyStore<I64, "i64.store", 0x37>;
-def STORE_F32  : WebAssemblyStore<F32, "f32.store", 0x38>;
-def STORE_F64  : WebAssemblyStore<F64, "f64.store", 0x39>;
+defm STORE_I32  : WebAssemblyStore<I32, "i32.store", 0x36>;
+defm STORE_I64  : WebAssemblyStore<I64, "i64.store", 0x37>;
+defm STORE_F32  : WebAssemblyStore<F32, "f32.store", 0x38>;
+defm STORE_F64  : WebAssemblyStore<F64, "f64.store", 0x39>;
 
 } // Defs = [ARGUMENTS]
 
 // Select stores with no constant offset.
-class StorePatNoOffset<ValueType ty, PatFrag node, I inst> :
+class StorePatNoOffset<ValueType ty, PatFrag node, NI inst> :
   Pat<(node ty:$val, I32:$addr), (inst 0, 0, $addr, $val)>;
 
 def : StorePatNoOffset<i32, store, STORE_I32>;
@@ -326,7 +334,7 @@ def : StorePatNoOffset<f32, store, STORE
 def : StorePatNoOffset<f64, store, STORE_F64>;
 
 // Select stores with a constant offset.
-class StorePatImmOff<ValueType ty, PatFrag storekind, PatFrag operand, I inst> :
+class StorePatImmOff<ValueType ty, PatFrag storekind, PatFrag operand, NI inst> :
   Pat<(storekind ty:$val, (operand I32:$addr, imm:$off)),
       (inst 0, imm:$off, $addr, ty:$val)>;
 
@@ -339,7 +347,7 @@ def : StorePatImmOff<i64, store, or_is_a
 def : StorePatImmOff<f32, store, or_is_add, STORE_F32>;
 def : StorePatImmOff<f64, store, or_is_add, STORE_F64>;
 
-class StorePatGlobalAddr<ValueType ty, PatFrag storekind, I inst> :
+class StorePatGlobalAddr<ValueType ty, PatFrag storekind, NI inst> :
   Pat<(storekind ty:$val, (regPlusGA I32:$addr,
                                      (WebAssemblywrapper tglobaladdr:$off))),
       (inst 0, tglobaladdr:$off, I32:$addr, ty:$val)>;
@@ -348,7 +356,7 @@ def : StorePatGlobalAddr<i64, store, STO
 def : StorePatGlobalAddr<f32, store, STORE_F32>;
 def : StorePatGlobalAddr<f64, store, STORE_F64>;
 
-class StorePatExternalSym<ValueType ty, PatFrag storekind, I inst> :
+class StorePatExternalSym<ValueType ty, PatFrag storekind, NI inst> :
   Pat<(storekind ty:$val, (add I32:$addr,
                                (WebAssemblywrapper texternalsym:$off))),
       (inst 0, texternalsym:$off, I32:$addr, ty:$val)>;
@@ -358,7 +366,7 @@ def : StorePatExternalSym<f32, store, ST
 def : StorePatExternalSym<f64, store, STORE_F64>;
 
 // Select stores with just a constant offset.
-class StorePatOffsetOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatOffsetOnly<ValueType ty, PatFrag storekind, NI inst> :
   Pat<(storekind ty:$val, imm:$off),
       (inst 0, imm:$off, (CONST_I32 0), ty:$val)>;
 def : StorePatOffsetOnly<i32, store, STORE_I32>;
@@ -366,7 +374,7 @@ def : StorePatOffsetOnly<i64, store, STO
 def : StorePatOffsetOnly<f32, store, STORE_F32>;
 def : StorePatOffsetOnly<f64, store, STORE_F64>;
 
-class StorePatGlobalAddrOffOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatGlobalAddrOffOnly<ValueType ty, PatFrag storekind, NI inst> :
   Pat<(storekind ty:$val, (WebAssemblywrapper tglobaladdr:$off)),
       (inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$val)>;
 def : StorePatGlobalAddrOffOnly<i32, store, STORE_I32>;
@@ -374,7 +382,7 @@ def : StorePatGlobalAddrOffOnly<i64, sto
 def : StorePatGlobalAddrOffOnly<f32, store, STORE_F32>;
 def : StorePatGlobalAddrOffOnly<f64, store, STORE_F64>;
 
-class StorePatExternSymOffOnly<ValueType ty, PatFrag storekind, I inst> :
+class StorePatExternSymOffOnly<ValueType ty, PatFrag storekind, NI inst> :
   Pat<(storekind ty:$val, (WebAssemblywrapper texternalsym:$off)),
       (inst 0, texternalsym:$off, (CONST_I32 0), ty:$val)>;
 def : StorePatExternSymOffOnly<i32, store, STORE_I32>;
@@ -386,11 +394,11 @@ def : StorePatExternSymOffOnly<f64, stor
 let Defs = [ARGUMENTS] in {
 
 // Truncating store.
-def STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
-def STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
-def STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>;
-def STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>;
-def STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>;
+defm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
+defm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
+defm STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>;
+defm STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>;
+defm STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>;
 
 } // Defs = [ARGUMENTS]
 
@@ -444,34 +452,47 @@ def : StorePatExternSymOffOnly<i64, trun
 let Defs = [ARGUMENTS] in {
 
 // Current memory size.
-def MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
-                        [(set I32:$dst, (int_wasm_memory_size (i32 imm:$flags)))],
-                        "memory.size\t$dst, $flags", 0x3f>,
-                      Requires<[HasAddr32]>;
-def MEM_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
-                     [(set I32:$dst, (int_wasm_mem_size (i32 imm:$flags)))],
-                     "mem.size\t$dst, $flags", 0x3f>,
-                   Requires<[HasAddr32]>;
-def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
-                           [],
-                           "current_memory\t$dst", 0x3f>,
-                         Requires<[HasAddr32]>;
+defm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+                         (outs), (ins i32imm:$flags),
+                         [(set I32:$dst,
+                           (int_wasm_memory_size (i32 imm:$flags)))],
+                         "memory.size\t$dst, $flags", "memory.size\t$flags",
+                         0x3f>,
+                       Requires<[HasAddr32]>;
+defm MEM_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+                      (outs), (ins i32imm:$flags),
+                      [(set I32:$dst, (int_wasm_mem_size (i32 imm:$flags)))],
+                      "mem.size\t$dst, $flags", "mem.size\t$flags", 0x3f>,
+                    Requires<[HasAddr32]>;
+defm CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
+                            (outs), (ins i32imm:$flags),
+                            [],
+                            "current_memory\t$dst",
+                            "current_memory\t$flags", 0x3f>,
+                          Requires<[HasAddr32]>;
 
 // Grow memory.
-def MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
-                        [(set I32:$dst,
-                              (int_wasm_memory_grow (i32 imm:$flags), I32:$delta))],
-                        "memory.grow\t$dst, $flags, $delta", 0x3f>,
-                      Requires<[HasAddr32]>;
-def MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
-                     [(set I32:$dst,
-                           (int_wasm_mem_grow (i32 imm:$flags), I32:$delta))],
-                     "mem.grow\t$dst, $flags, $delta", 0x3f>,
-                   Requires<[HasAddr32]>;
-def GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
-                        [],
-                        "grow_memory\t$dst, $delta", 0x40>,
-                      Requires<[HasAddr32]>;
+defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+                         (outs), (ins i32imm:$flags, I32:$delta),
+                         [(set I32:$dst,
+                           (int_wasm_memory_grow (i32 imm:$flags),
+                             I32:$delta))],
+                         "memory.grow\t$dst, $flags, $delta",
+                         "memory.grow\t$flags, $delta", 0x3f>,
+                       Requires<[HasAddr32]>;
+defm MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+                      (outs), (ins i32imm:$flags),
+                      [(set I32:$dst,
+                            (int_wasm_mem_grow (i32 imm:$flags), I32:$delta))],
+                      "mem.grow\t$dst, $flags, $delta", "mem.grow\t$flags",
+                      0x3f>,
+                    Requires<[HasAddr32]>;
+defm GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
+                         (outs), (ins i32imm:$flags),
+                         [],
+                         "grow_memory\t$dst, $delta", "grow_memory\t$flags",
+                         0x40>,
+                       Requires<[HasAddr32]>;
 
 } // Defs = [ARGUMENTS]
 

Modified: llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt?rev=334985&r1=334984&r2=334985&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt (original)
+++ llvm/trunk/test/MC/Disassembler/WebAssembly/wasm.txt Mon Jun 18 14:22:44 2018
@@ -5,14 +5,14 @@
 # CHECK: nop
 0x01
 
-# CHECK: i32.add $0=, $0, $0
-# NOTE: registers are meaningless, as there is no context for what they are.
+# CHECK: i32.add
 0x6a
 
-# CHECK: i64.const $0=, -1
+# CHECK: i64.const -1
 0x42 0x7F
 
-# CHECK: i64.load32_u $0=, 16($0):p2align=1
+# CHECK: i64.load32_u 16, :p2align=1
+# FIXME: fix p2align output in WebAssemblyInstPrinter
 0x35 0x01 0x10
 
 # CHECK: block
@@ -25,9 +25,9 @@
 # FIXME: WebAssemblyInstPrinter does not print immediates.
 0x11 0x80 0x01 0x00
 
-# CHECK: get_local $0=, 128
+# CHECK: get_local 128
 0x20 0x80 0x01
 
 # Prefix byte example:
-# CHECK: i64.trunc_u:sat/f64 $0=, $0
+# CHECK: i64.trunc_u:sat/f64
 0xFC 0x07




More information about the llvm-commits mailing list