blob: 6aae5d38d0b51d280d93b9e2b30844e3d867e1ae [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),
Hans Wennborg7384a2d2015-11-12 14:37:56 +000044 [(WebAssemblyswitch I32:$index)]>;
Dan Gohmand0bf9812015-09-26 01:09:44 +000045def SWITCH_I64 : I<(outs), (ins I64:$index, variable_ops),
Hans Wennborg7384a2d2015-11-12 14:37:56 +000046 [(WebAssemblyswitch I64:$index)]>;
Dan Gohman950a13c2015-09-16 16:51:30 +000047} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
48
49// Placemarkers to indicate the start of a block or loop scope.
Dan Gohmanaf29bd42015-11-05 20:42:30 +000050def BLOCK : I<(outs), (ins bb_op:$dst), [], "block $dst">;
51def LOOP : I<(outs), (ins bb_op:$dst), [], "loop $dst">;
Dan Gohman950a13c2015-09-16 16:51:30 +000052
JF Bastien8f9aea02015-08-01 04:48:44 +000053multiclass RETURN<WebAssemblyRegClass vt> {
Dan Gohmanaf29bd42015-11-05 20:42:30 +000054 def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
55 "return $val">;
JF Bastien8f9aea02015-08-01 04:48:44 +000056}
Derek Schuffffa143c2015-11-10 00:30:57 +000057
58let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
59let isReturn = 1 in {
Dan Gohmand0bf9812015-09-26 01:09:44 +000060 defm : RETURN<I32>;
61 defm : RETURN<I64>;
62 defm : RETURN<F32>;
63 defm : RETURN<F64>;
Dan Gohmanaf29bd42015-11-05 20:42:30 +000064 def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">;
Derek Schuffffa143c2015-11-10 00:30:57 +000065} // isReturn = 1
66 def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">;
67} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1