[llvm] [WebAssembly] Support disassembler for try_table (PR #108800)

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 16 00:34:21 PDT 2024


https://github.com/aheejin created https://github.com/llvm/llvm-project/pull/108800

This adds support for disassembler for the new `try_table` instruction. This adds tests for `throw` and `throw_ref` as well.

Currently tag expressions are not supported for `throw` or `try_table` instruction when instructions are parsed from the disassembler. Not sure whether there is a way to support it. (This is not a new thing for the new EH proposal; it has not been supported for the legacy EH as well.)

>From 6115882cc3d4d7a6cf8d153ff280b280fd1f0476 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Mon, 16 Sep 2024 03:49:40 +0000
Subject: [PATCH] [WebAssembly] Support disassembler for try_table

This adds support for disassembler for the new `try_table` instruction.
This adds tests for `throw` and `throw_ref` as well.

Currently tag expressions are not supported for `throw` or `try_table`
instruction when instructions are parsed from the disassembler. Not sure
whether there is a way to support it. (This is not a new thing for the
new EH proposal; it has not been supported for the legacy EH as well.)
---
 .../Disassembler/WebAssemblyDisassembler.cpp   | 18 ++++++++++++++++++
 .../MCTargetDesc/WebAssemblyInstPrinter.cpp    | 13 +++++++++----
 llvm/test/MC/Disassembler/WebAssembly/wasm.txt |  7 +++++++
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
index 3585b5f4a5c9ad..a66ee2b6ac1af7 100644
--- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -289,6 +289,24 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
         return MCDisassembler::Fail;
       break;
     }
+    case WebAssembly::OPERAND_CATCH_LIST: {
+      if (!parseLEBImmediate(MI, Size, Bytes, false))
+        return MCDisassembler::Fail;
+      int64_t NumCatches = MI.getOperand(MI.getNumOperands() - 1).getImm();
+      for (int64_t I = 0; I < NumCatches; I++) {
+        if (!parseImmediate<uint8_t>(MI, Size, Bytes))
+          return MCDisassembler::Fail;
+        int64_t CatchOpcode = MI.getOperand(MI.getNumOperands() - 1).getImm();
+        if (CatchOpcode == wasm::WASM_OPCODE_CATCH ||
+            CatchOpcode == wasm::WASM_OPCODE_CATCH_REF) {
+          if (!parseLEBImmediate(MI, Size, Bytes, false)) // tag index
+            return MCDisassembler::Fail;
+        }
+        if (!parseLEBImmediate(MI, Size, Bytes, false)) // destination
+          return MCDisassembler::Fail;
+      }
+      break;
+    }
     case MCOI::OPERAND_REGISTER:
       // The tablegen header currently does not have any register operands since
       // we use only the stack (_S) instructions.
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 903dbcd21ea967..7255195fbaab31 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -377,10 +377,15 @@ void WebAssemblyInstPrinter::printCatchList(const MCInst *MI, unsigned OpNo,
   auto PrintTagOp = [&](const MCOperand &Op) {
     const MCSymbolRefExpr *TagExpr = nullptr;
     const MCSymbolWasm *TagSym = nullptr;
-    assert(Op.isExpr());
-    TagExpr = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
-    TagSym = cast<MCSymbolWasm>(&TagExpr->getSymbol());
-    O << TagSym->getName() << " ";
+    if (Op.isExpr()) {
+      TagExpr = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
+      TagSym = cast<MCSymbolWasm>(&TagExpr->getSymbol());
+      O << TagSym->getName() << " ";
+    } else {
+      // When instructions are parsed from the disassembler, we have an
+      // immediate tag index and not a tag expr
+      O << Op.getImm() << " ";
+    }
   };
 
   for (unsigned I = 0; I < NumCatches; I++) {
diff --git a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
index 0cbf584d9688e1..f6a3527fc5ed12 100644
--- a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
+++ b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
@@ -53,3 +53,10 @@
 # This can mean end_block/end_loop/end_if/end_function/end_try..
 # CHECK: end
 0x0B
+
+# CHECK:  try_table        (catch 0 0) (catch_ref 0 1) (catch_all 2) (catch_all_ref 3)
+0x1F 0x40 0x04 0x00 0x00 0x00 0x01 0x00 0x01 0x02 0x02 0x03 0x03
+# CHECK: throw 0
+0x08 0x00
+# CHECK: throw_ref
+0x0a



More information about the llvm-commits mailing list