summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2018-11-09 01:57:00 +0000
committerThomas Lively <tlively@google.com>2018-11-09 01:57:00 +0000
commit2faf079494e90c1a941cf1bf51c8e7abb19bcef9 (patch)
tree7d5a9c9d963a109a9414f7a90c63b9d1c5633c2c
parent4ddd22581ee547c20222a4aba3a598803eb99a1e (diff)
downloadbcm5719-llvm-2faf079494e90c1a941cf1bf51c8e7abb19bcef9.tar.gz
bcm5719-llvm-2faf079494e90c1a941cf1bf51c8e7abb19bcef9.zip
[WebAssembly] Read prefixed opcodes as ULEB128s
Summary: Depends on D54126. Reviewers: aheejin, dschuff, aardappel Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D54138 llvm-svn: 346465
-rw-r--r--llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp32
-rw-r--r--llvm/test/MC/Disassembler/WebAssembly/wasm.txt9
-rw-r--r--llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp6
3 files changed, 35 insertions, 12 deletions
diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
index 54403a56274..4ab290399ba 100644
--- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -66,7 +66,7 @@ extern "C" void LLVMInitializeWebAssemblyDisassembler() {
createWebAssemblyDisassembler);
}
-static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) {
+static uint8_t nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) {
if (Size >= Bytes.size())
return -1;
auto V = Bytes[Size];
@@ -74,18 +74,26 @@ static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) {
return V;
}
-static bool parseLEBImmediate(MCInst &MI, uint64_t &Size,
- ArrayRef<uint8_t> Bytes, bool Signed) {
+static bool nextLEB(int64_t &Val, ArrayRef<uint8_t> Bytes, uint64_t &Size,
+ bool Signed = false) {
unsigned N = 0;
const char *Error = nullptr;
- auto Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N,
- Bytes.data() + Bytes.size(), &Error)
- : static_cast<int64_t>(
- decodeULEB128(Bytes.data() + Size, &N,
- Bytes.data() + Bytes.size(), &Error));
+ Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N,
+ Bytes.data() + Bytes.size(), &Error)
+ : static_cast<int64_t>(decodeULEB128(Bytes.data() + Size, &N,
+ Bytes.data() + Bytes.size(),
+ &Error));
if (Error)
return false;
Size += N;
+ return true;
+}
+
+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;
}
@@ -127,10 +135,12 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
}
if (!WasmInst)
return MCDisassembler::Fail;
- Opc = nextByte(Bytes, Size);
- if (Opc < 0)
+ int64_t PrefixedOpc;
+ if (!nextLEB(PrefixedOpc, Bytes, Size))
+ return MCDisassembler::Fail;
+ if (PrefixedOpc < 0 || PrefixedOpc >= WebAssemblyInstructionTableSize)
return MCDisassembler::Fail;
- WasmInst += Opc;
+ WasmInst += PrefixedOpc;
}
if (WasmInst->ET == ET_Unused)
return MCDisassembler::Fail;
diff --git a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
index dedeae6e408..fd21db9ad47 100644
--- a/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
+++ b/llvm/test/MC/Disassembler/WebAssembly/wasm.txt
@@ -37,3 +37,12 @@
# CHECK: v8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
0xFD 0x03 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
+
+# Check LEB128 encoding of SIMD instructions
+# CHECK: i64x2.all_true
+0xFD 0x86 0x01
+
+# Including non-canonical LEB128 encodings
+# CHECK: i64x2.any_true
+# CHECK-NOT: i64.div_u
+0xFD 0x85 0x81 0x80 0x80 0x80 0x80 0x00
diff --git a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
index a8edfdc623f..ab785715d97 100644
--- a/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
+++ b/llvm/utils/TableGen/WebAssemblyDisassemblerEmitter.cpp
@@ -19,6 +19,8 @@
namespace llvm {
+static constexpr int WebAssemblyInstructionTableSize = 256;
+
void emitWebAssemblyDisassemblerTables(
raw_ostream &OS,
const ArrayRef<const CodeGenInstruction *> &NumberedInstructions) {
@@ -59,6 +61,8 @@ void emitWebAssemblyDisassemblerTables(
OS << "#include \"MCTargetDesc/WebAssemblyMCTargetDesc.h\"\n";
OS << "\n";
OS << "namespace llvm {\n\n";
+ OS << "static constexpr int WebAssemblyInstructionTableSize = ";
+ OS << WebAssemblyInstructionTableSize << ";\n\n";
OS << "enum EntryType : uint8_t { ";
OS << "ET_Unused, ET_Prefix, ET_Instruction };\n\n";
OS << "struct WebAssemblyInstruction {\n";
@@ -74,7 +78,7 @@ void emitWebAssemblyDisassemblerTables(
continue;
OS << "WebAssemblyInstruction InstructionTable" << PrefixPair.first;
OS << "[] = {\n";
- for (unsigned I = 0; I <= 0xFF; I++) {
+ for (unsigned I = 0; I < WebAssemblyInstructionTableSize; I++) {
auto InstIt = PrefixPair.second.find(I);
if (InstIt != PrefixPair.second.end()) {
// Regular instruction.
OpenPOWER on IntegriCloud