X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FWebAssembly%2FWebAssemblyInstrControl.td;h=9a9468bb3909c242c85c04ee0f0445d9a5c544cf;hp=af73a93c2079afc8a054393cd2cdeb28c7204541;hb=577f887f754894edf6d8093ddca72ff69f0659ec;hpb=284e00c04e6fb5ba4cb413b6b1e2b1b0152d89fa diff --git a/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/lib/Target/WebAssembly/WebAssemblyInstrControl.td index af73a93c207..9a9468bb390 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -12,36 +12,56 @@ /// //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { + let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { -def BR_IF : I<(outs), (ins bb_op:$dst, I32:$a), - [(brcond I32:$a, bb:$dst)], - "br_if\t$dst, $a">; +// The condition operand is a boolean value which WebAssembly represents as i32. +def BR_IF : I<(outs), (ins I32:$cond, bb_op:$dst), + [(brcond I32:$cond, bb:$dst)], + "br_if \t$cond, $dst">; +let isCodeGenOnly = 1 in +def BR_UNLESS : I<(outs), (ins I32:$cond, bb_op:$dst), [], + "br_unless\t$cond, $dst">; let isBarrier = 1 in { def BR : I<(outs), (ins bb_op:$dst), [(br bb:$dst)], - "br\t$dst">; + "br \t$dst">; } // isBarrier = 1 } // isBranch = 1, isTerminator = 1, hasCtrlDep = 1 +} // Defs = [ARGUMENTS] + +def : Pat<(brcond (i32 (setne I32:$cond, 0)), bb:$dst), + (BR_IF I32:$cond, bb_op:$dst)>; +def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst), + (BR_UNLESS I32:$cond, bb_op:$dst)>; + +let Defs = [ARGUMENTS] in { + // TODO: SelectionDAG's lowering insists on using a pointer as the index for -// jump tables, so in practice we don't ever use SWITCH_I64 in wasm32 mode +// jump tables, so in practice we don't ever use TABLESWITCH_I64 in wasm32 mode // currently. let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { -def SWITCH_I32 : I<(outs), (ins I32:$index, variable_ops), - [(WebAssemblyswitch I32:$index)], - "switch\t$index">; -def SWITCH_I64 : I<(outs), (ins I64:$index, variable_ops), - [(WebAssemblyswitch I64:$index)], - "switch\t$index">; +def TABLESWITCH_I32 : I<(outs), (ins I32:$index, bb_op:$default, variable_ops), + [(WebAssemblytableswitch I32:$index, bb:$default)], + "tableswitch\t$index, $default">; +def TABLESWITCH_I64 : I<(outs), (ins I64:$index, bb_op:$default, variable_ops), + [(WebAssemblytableswitch I64:$index, bb:$default)], + "tableswitch\t$index, $default">; } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 // Placemarkers to indicate the start of a block or loop scope. -def BLOCK : I<(outs), (ins bb_op:$dst), [], "block\t$dst">; -def LOOP : I<(outs), (ins bb_op:$dst), [], "loop\t$dst">; +def BLOCK : I<(outs), (ins bb_op:$dst), [], "block \t$dst">; +def LOOP : I<(outs), (ins bb_op:$dst), [], "loop \t$dst">; + +// No-op to indicate to the AsmPrinter that a loop ends here, so a +// basic block label is needed even if it wouldn't otherwise appear so. +let isTerminator = 1, hasCtrlDep = 1 in +def LOOP_END : I<(outs), (ins), []>; multiclass RETURN { def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)], - "return\t$val">; + "return \t$val">; } let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { @@ -54,3 +74,5 @@ let isReturn = 1 in { } // isReturn = 1 def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">; } // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 + +} // Defs = [ARGUMENTS]