1296417Sdim//=- WebAssemblyInstrFormats.td - WebAssembly Instr. Formats -*- tablegen -*-=//
2285163Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6285163Sdim//
7285163Sdim//===----------------------------------------------------------------------===//
8286684Sdim///
9286684Sdim/// \file
10341825Sdim/// WebAssembly instruction format definitions.
11286684Sdim///
12285163Sdim//===----------------------------------------------------------------------===//
13285163Sdim
14296417Sdim// WebAssembly Instruction Format.
15341825Sdim// We instantiate 2 of these for every actual instruction (register based
16341825Sdim// and stack based), see below.
17344779Sdimclass WebAssemblyInst<bits<32> inst, string asmstr, string stack> : StackRel,
18344779Sdim  Instruction {
19344779Sdim  bits<32> Inst = inst; // Instruction encoding.
20344779Sdim  string StackBased = stack;
21344779Sdim  string BaseName = NAME;
22285163Sdim  let Namespace   = "WebAssembly";
23285163Sdim  let Pattern     = [];
24296417Sdim  let AsmString   = asmstr;
25353358Sdim  // When there are multiple instructions that map to the same encoding (in
26353358Sdim  // e.g. the disassembler use case) prefer the one where IsCanonical == 1.
27353358Sdim  bit IsCanonical = 0;
28285163Sdim}
29285163Sdim
30341825Sdim// Normal instructions. Default instantiation of a WebAssemblyInst.
31344779Sdimclass NI<dag oops, dag iops, list<dag> pattern, string stack,
32344779Sdim         string asmstr = "", bits<32> inst = -1>
33341825Sdim    : WebAssemblyInst<inst, asmstr, stack> {
34285163Sdim  dag OutOperandList = oops;
35285163Sdim  dag InOperandList  = iops;
36285163Sdim  let Pattern        = pattern;
37344779Sdim  let Defs           = [ARGUMENTS];
38285163Sdim}
39286684Sdim
40341825Sdim// Generates both register and stack based versions of one actual instruction.
41341825Sdim// We have 2 sets of operands (oops & iops) for the register and stack
42341825Sdim// based version of this instruction, as well as the corresponding asmstr.
43341825Sdim// The register versions have virtual-register operands which correspond to wasm
44341825Sdim// locals or stack locations. Each use and def of the register corresponds to an
45344779Sdim// implicit local.get / local.set or access of stack operands in wasm. These
46341825Sdim// instructions are used for ISel and all MI passes. The stack versions of the
47341825Sdim// instructions do not have register operands (they implicitly operate on the
48344779Sdim// stack), and local.gets and local.sets are explicit. The register instructions
49341825Sdim// are converted to their corresponding stack instructions before lowering to
50341825Sdim// MC.
51341825Sdim// Every instruction should want to be based on this multi-class to guarantee
52341825Sdim// there is always an equivalent pair of instructions.
53341825Sdimmulticlass I<dag oops_r, dag iops_r, dag oops_s, dag iops_s,
54341825Sdim             list<dag> pattern_r, string asmstr_r = "", string asmstr_s = "",
55341825Sdim             bits<32> inst = -1> {
56344779Sdim  let isCodeGenOnly = 1 in
57344779Sdim  def "" : NI<oops_r, iops_r, pattern_r, "false", asmstr_r, inst>;
58344779Sdim  let BaseName = NAME in
59344779Sdim  def _S : NI<oops_s, iops_s, [], "true", asmstr_s, inst>;
60341825Sdim}
61314564Sdim
62341825Sdim// For instructions that have no register ops, so both sets are the same.
63341825Sdimmulticlass NRI<dag oops, dag iops, list<dag> pattern, string asmstr = "",
64341825Sdim               bits<32> inst = -1> {
65341825Sdim  defm "": I<oops, iops, oops, iops, pattern, asmstr, asmstr, inst>;
66341825Sdim}
67