-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebAssembly] Support disassembler for try_table #108800
Conversation
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.)
@llvm/pr-subscribers-backend-webassembly Author: Heejin Ahn (aheejin) ChangesThis adds support for disassembler for the new Currently tag expressions are not supported for Full diff: https://github.com/llvm/llvm-project/pull/108800.diff 3 Files Affected:
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
|
@llvm/pr-subscribers-mc Author: Heejin Ahn (aheejin) ChangesThis adds support for disassembler for the new Currently tag expressions are not supported for Full diff: https://github.com/llvm/llvm-project/pull/108800.diff 3 Files Affected:
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
|
case WebAssembly::OPERAND_CATCH_LIST: { | ||
if (!parseLEBImmediate(MI, Size, Bytes, false)) | ||
return MCDisassembler::Fail; | ||
int64_t NumCatches = MI.getOperand(MI.getNumOperands() - 1).getImm(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where do these operands actually get added to the MI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In those parse***
functions. For example:
llvm-project/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
Lines 101 to 108 in 6ca5c39
static bool parseLEBImmediate(MCInst &MI, uint64_t &Size, | |
ArrayRef<uint8_t> Bytes, bool Signed) { | |
int64_t Val; | |
if (!nextLEB(Val, Bytes, Size, Signed)) | |
return false; | |
MI.addOperand(MCOperand::createImm(Val)); | |
return true; | |
} |
Yeah it was a little confusing to me too so I had to look into those functions...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, the number of catches is the last operand currently, because we haven't parsed the rest yet.
case WebAssembly::OPERAND_CATCH_LIST: { | ||
if (!parseLEBImmediate(MI, Size, Bytes, false)) | ||
return MCDisassembler::Fail; | ||
int64_t NumCatches = MI.getOperand(MI.getNumOperands() - 1).getImm(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, the number of catches is the last operand currently, because we haven't parsed the rest yet.
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.)
This adds support for disassembler for the new
try_table
instruction. This adds tests forthrow
andthrow_ref
as well.Currently tag expressions are not supported for
throw
ortry_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.)