]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Added basic support for if/else/end_if in MC layer.
authorWouter van Oortmerssen <aardappel@gmail.com>
Wed, 26 Dec 2018 22:55:26 +0000 (22:55 +0000)
committerWouter van Oortmerssen <aardappel@gmail.com>
Wed, 26 Dec 2018 22:55:26 +0000 (22:55 +0000)
Summary:
These instructions are currently unused in our backend, but for
completeness it is good to support them, so they can be used with
the assembler in hand-written code.

Tests are very basic, signature support missing much like other blocks.

Reviewers: dschuff, aheejin

Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350079 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
lib/Target/WebAssembly/WebAssemblyInstrControl.td
test/MC/WebAssembly/basic-assembly.s

index 62229d390b3c7168277398b4861c472aa2679987..d997190aa3666afa5b9df1aca3c67843aa811af8 100644 (file)
@@ -488,7 +488,8 @@ public:
     // assembly, so we add a dummy one explicitly (since we have no control
     // over signature tables here, we assume these will be regenerated when
     // the wasm module is generated).
-    if (BaseName == "block" || BaseName == "loop" || BaseName == "try") {
+    if (BaseName == "block" || BaseName == "loop" || BaseName == "try" ||
+        BaseName == "if") {
       Operands.push_back(make_unique<WebAssemblyOperand>(
           WebAssemblyOperand::Integer, NameLoc, NameLoc,
           WebAssemblyOperand::IntOp{-1}));
index a7fc7564009007474825f53e500007dc8bf5deb7..021f95feec8da4c8fb76275da55ba875e4d865b8 100644 (file)
@@ -75,13 +75,19 @@ defm NOP : NRI<(outs), (ins), [], "nop", 0x01>;
 // 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 {
-defm BLOCK     : NRI<(outs), (ins Signature:$sig), [], "block   \t$sig", 0x02>;
-defm LOOP      : NRI<(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.
+defm IF : I<(outs), (ins Signature:$sig, I32:$cond),
+            (outs), (ins Signature:$sig),
+            [], "if    \t$sig, $cond", "if    \t$sig", 0x04>;
+defm ELSE : NRI<(outs), (ins), [], "else", 0x05>;
+
+// END_BLOCK, END_LOOP, END_IF and END_FUNCTION are represented with the same
+// opcode in wasm.
 defm END_BLOCK : NRI<(outs), (ins), [], "end_block", 0x0b>;
 defm END_LOOP  : NRI<(outs), (ins), [], "end_loop", 0x0b>;
+defm END_IF    : NRI<(outs), (ins), [], "end_if", 0x0b>;
 let isTerminator = 1, isBarrier = 1 in
 defm END_FUNCTION : NRI<(outs), (ins), [], "end_function", 0x0b>;
 } // Uses = [VALUE_STACK], Defs = [VALUE_STACK]
index e29e47d80aa9c20ee9ff61ea5bed9af2192ce8a7..684d40debfe70791d6fd7c5507d73a9ae2d8daca 100644 (file)
@@ -59,11 +59,11 @@ test0:
     end_block            # default jumps here.
     i32.const 3
     end_block            # "switch" exit.
-    #if                  # These are not in tablegen defs yet..
-    #if
-    #end_if
-    #else
-    #end_if
+    if
+    if
+    end_if
+    else
+    end_if
     f32x4.add
     # Test correct parsing of instructions with / and : in them:
     # TODO: enable once instruction has been added.
@@ -134,11 +134,11 @@ test0:
 # CHECK-NEXT:      end_block           # label3:
 # CHECK-NEXT:      i32.const 3
 # CHECK-NEXT:      end_block           # label2:
-# DONT-CHECK-NEXT:      if
-# DONT-CHECK-NEXT:      if
-# DONT-CHECK-NEXT:      end_if
-# DONT-CHECK-NEXT:      else
-# DONT-CHECK-NEXT:      end_if
+# CHECK-NEXT:      if
+# CHECK-NEXT:      if
+# CHECK-NEXT:      end_if
+# CHECK-NEXT:      else
+# CHECK-NEXT:      end_if
 # CHECK-NEXT:      f32x4.add
 # CHECK-NEXT:      i32.trunc_s/f32
 # CHECK-NEXT:      try