[WebAssembly] Use a physical register to describe ARGUMENT liveness.
[oota-llvm.git] / lib / Target / WebAssembly / WebAssemblyInstrControl.td
1 //===- WebAssemblyInstrControl.td-WebAssembly control-flow ------*- tablegen -*-
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief WebAssembly control-flow code-gen constructs.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 let Defs = [ARGUMENTS] in {
16
17 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
18 def BR_IF : I<(outs), (ins I32:$a, bb_op:$dst),
19               [(brcond I32:$a, bb:$dst)],
20                "br_if   \t$a, $dst">;
21 let isBarrier = 1 in {
22 def BR   : I<(outs), (ins bb_op:$dst),
23              [(br bb:$dst)],
24              "br      \t$dst">;
25 } // isBarrier = 1
26 } // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
27
28 // TODO: SelectionDAG's lowering insists on using a pointer as the index for
29 // jump tables, so in practice we don't ever use TABLESWITCH_I64 in wasm32 mode
30 // currently.
31 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
32 def TABLESWITCH_I32 : I<(outs), (ins I32:$index, variable_ops),
33                         [(WebAssemblytableswitch I32:$index)],
34                         "tableswitch\t$index">;
35 def TABLESWITCH_I64 : I<(outs), (ins I64:$index, variable_ops),
36                         [(WebAssemblytableswitch I64:$index)],
37                         "tableswitch\t$index">;
38 } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
39
40 // Placemarkers to indicate the start of a block or loop scope.
41 def BLOCK     : I<(outs), (ins bb_op:$dst), [], "block   \t$dst">;
42 def LOOP      : I<(outs), (ins bb_op:$dst), [], "loop    \t$dst">;
43
44 // No-op to indicate to the AsmPrinter that a loop ends here, so a
45 // basic block label is needed even if it wouldn't otherwise appear so.
46 let isTerminator = 1, hasCtrlDep = 1 in
47 def LOOP_END : I<(outs), (ins), []>;
48
49 multiclass RETURN<WebAssemblyRegClass vt> {
50   def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
51                      "return  \t$val">;
52 }
53
54 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
55 let isReturn = 1 in {
56   defm : RETURN<I32>;
57   defm : RETURN<I64>;
58   defm : RETURN<F32>;
59   defm : RETURN<F64>;
60   def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">;
61 } // isReturn = 1
62   def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">;
63 } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
64
65 } // Defs = [ARGUMENTS]