blob: acfd738a8fa839835b5f9689cd84751ae2fe3658 [file] [log] [blame]
JF Bastien600aee92015-07-31 17:53:38 +00001//===- 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/*
16 * TODO(jfb): Add the following.
17 *
18 * block: a fixed-length sequence of statements
19 * if: if statement
20 * do_while: do while statement, basically a loop with a conditional branch
21 * forever: infinite loop statement (like while (1)), basically an unconditional
22 * branch (back to the top of the loop)
23 * continue: continue to start of nested loop
24 * break: break to end from nested loop or block
25 * switch: switch statement with fallthrough
26 */
27
Dan Gohman950a13c2015-09-16 16:51:30 +000028let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
JF Bastien3b0177c2015-10-20 00:37:42 +000029def BR_IF_ : I<(outs), (ins bb_op:$dst, I32:$a),
Dan Gohmanaf29bd42015-11-05 20:42:30 +000030 [(brcond I32:$a, bb:$dst)],
31 "br_if $dst, $a">;
Dan Gohman950a13c2015-09-16 16:51:30 +000032let isBarrier = 1 in {
33def BR : I<(outs), (ins bb_op:$dst),
Dan Gohmanaf29bd42015-11-05 20:42:30 +000034 [(br bb:$dst)],
35 "br $dst">;
Dan Gohman950a13c2015-09-16 16:51:30 +000036} // isBarrier = 1
37} // isBranch = 1, isTerminator = 1, hasCtrlDep = 1
38
39// TODO: SelectionDAG's lowering insists on using a pointer as the index for
40// jump tables, so in practice we don't ever use SWITCH_I64 in wasm32 mode
41// currently.
42let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
Dan Gohmand0bf9812015-09-26 01:09:44 +000043def SWITCH_I32 : I<(outs), (ins I32:$index, variable_ops),
Dan Gohmancf4748f2015-11-12 17:04:33 +000044 [(WebAssemblyswitch I32:$index)],
45 "switch $index">;
Dan Gohmand0bf9812015-09-26 01:09:44 +000046def SWITCH_I64 : I<(outs), (ins I64:$index, variable_ops),
Dan Gohmancf4748f2015-11-12 17:04:33 +000047 [(WebAssemblyswitch I64:$index)],
48 "switch $index">;
Dan Gohman950a13c2015-09-16 16:51:30 +000049} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
50
51// Placemarkers to indicate the start of a block or loop scope.
Dan Gohmanaf29bd42015-11-05 20:42:30 +000052def BLOCK : I<(outs), (ins bb_op:$dst), [], "block $dst">;
53def LOOP : I<(outs), (ins bb_op:$dst), [], "loop $dst">;
Dan Gohman950a13c2015-09-16 16:51:30 +000054
JF Bastien8f9aea02015-08-01 04:48:44 +000055multiclass RETURN<WebAssemblyRegClass vt> {
Dan Gohmanaf29bd42015-11-05 20:42:30 +000056 def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
57 "return $val">;
JF Bastien8f9aea02015-08-01 04:48:44 +000058}
Derek Schuffffa143c2015-11-10 00:30:57 +000059
60let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
61let isReturn = 1 in {
Dan Gohmand0bf9812015-09-26 01:09:44 +000062 defm : RETURN<I32>;
63 defm : RETURN<I64>;
64 defm : RETURN<F32>;
65 defm : RETURN<F64>;
Dan Gohmanaf29bd42015-11-05 20:42:30 +000066 def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">;
Derek Schuffffa143c2015-11-10 00:30:57 +000067} // isReturn = 1
68 def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">;
69} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1