10b57cec5SDimitry Andric//=- WebAssemblyInstrFormats.td - WebAssembly Instr. Formats -*- tablegen -*-=// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric/// 90b57cec5SDimitry Andric/// \file 100b57cec5SDimitry Andric/// WebAssembly instruction format definitions. 110b57cec5SDimitry Andric/// 120b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric// WebAssembly Instruction Format. 150b57cec5SDimitry Andric// We instantiate 2 of these for every actual instruction (register based 160b57cec5SDimitry Andric// and stack based), see below. 17*81ad6265SDimitry Andricclass WebAssemblyInst<bits<32> inst, string asmstr, bit stack, bit is64> 18fe6060f1SDimitry Andric : StackRel, RegisterRel, Wasm64Rel, Instruction { 190b57cec5SDimitry Andric bits<32> Inst = inst; // Instruction encoding. 20*81ad6265SDimitry Andric bit StackBased = stack; 210b57cec5SDimitry Andric string BaseName = NAME; 22*81ad6265SDimitry Andric bit IsWasm64 = is64; 235ffd83dbSDimitry Andric string Wasm32Name = !subst("_A64", "_A32", NAME); 240b57cec5SDimitry Andric let Namespace = "WebAssembly"; 250b57cec5SDimitry Andric let Pattern = []; 260b57cec5SDimitry Andric let AsmString = asmstr; 270b57cec5SDimitry Andric // When there are multiple instructions that map to the same encoding (in 280b57cec5SDimitry Andric // e.g. the disassembler use case) prefer the one where IsCanonical == 1. 290b57cec5SDimitry Andric bit IsCanonical = 0; 300b57cec5SDimitry Andric} 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric// Normal instructions. Default instantiation of a WebAssemblyInst. 33*81ad6265SDimitry Andricclass NI<dag oops, dag iops, list<dag> pattern, bit stack, 34*81ad6265SDimitry Andric string asmstr = "", bits<32> inst = -1, bit is64 = false> 355ffd83dbSDimitry Andric : WebAssemblyInst<inst, asmstr, stack, is64> { 360b57cec5SDimitry Andric dag OutOperandList = oops; 370b57cec5SDimitry Andric dag InOperandList = iops; 380b57cec5SDimitry Andric let Pattern = pattern; 390b57cec5SDimitry Andric let Defs = [ARGUMENTS]; 400b57cec5SDimitry Andric} 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric// Generates both register and stack based versions of one actual instruction. 430b57cec5SDimitry Andric// We have 2 sets of operands (oops & iops) for the register and stack 440b57cec5SDimitry Andric// based version of this instruction, as well as the corresponding asmstr. 450b57cec5SDimitry Andric// The register versions have virtual-register operands which correspond to wasm 460b57cec5SDimitry Andric// locals or stack locations. Each use and def of the register corresponds to an 470b57cec5SDimitry Andric// implicit local.get / local.set or access of stack operands in wasm. These 480b57cec5SDimitry Andric// instructions are used for ISel and all MI passes. The stack versions of the 490b57cec5SDimitry Andric// instructions do not have register operands (they implicitly operate on the 500b57cec5SDimitry Andric// stack), and local.gets and local.sets are explicit. The register instructions 510b57cec5SDimitry Andric// are converted to their corresponding stack instructions before lowering to 520b57cec5SDimitry Andric// MC. 530b57cec5SDimitry Andric// Every instruction should want to be based on this multi-class to guarantee 540b57cec5SDimitry Andric// there is always an equivalent pair of instructions. 550b57cec5SDimitry Andricmulticlass I<dag oops_r, dag iops_r, dag oops_s, dag iops_s, 560b57cec5SDimitry Andric list<dag> pattern_r, string asmstr_r = "", string asmstr_s = "", 57*81ad6265SDimitry Andric bits<32> inst = -1, bit is64 = false> { 580b57cec5SDimitry Andric let isCodeGenOnly = 1 in 59*81ad6265SDimitry Andric def "" : NI<oops_r, iops_r, pattern_r, false, asmstr_r, inst, is64>; 600b57cec5SDimitry Andric let BaseName = NAME in 61*81ad6265SDimitry Andric def _S : NI<oops_s, iops_s, [], true, asmstr_s, inst, is64>; 620b57cec5SDimitry Andric} 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric// For instructions that have no register ops, so both sets are the same. 650b57cec5SDimitry Andricmulticlass NRI<dag oops, dag iops, list<dag> pattern, string asmstr = "", 660b57cec5SDimitry Andric bits<32> inst = -1> { 670b57cec5SDimitry Andric defm "": I<oops, iops, oops, iops, pattern, asmstr, asmstr, inst>; 680b57cec5SDimitry Andric} 69