diff options
Diffstat (limited to 'lib/Target/WebAssembly/WebAssemblyInstrInteger.td')
| -rw-r--r-- | lib/Target/WebAssembly/WebAssemblyInstrInteger.td | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/lib/Target/WebAssembly/WebAssemblyInstrInteger.td index f9f21fd1d754..d5b63d643697 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -12,7 +12,38 @@ /// //===----------------------------------------------------------------------===// -let Defs = [ARGUMENTS] in { +multiclass UnaryInt<SDNode node, string name, bits<32> i32Inst, + bits<32> i64Inst> { + defm _I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), + [(set I32:$dst, (node I32:$src))], + !strconcat("i32.", !strconcat(name, "\t$dst, $src")), + !strconcat("i32.", name), i32Inst>; + defm _I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), + [(set I64:$dst, (node I64:$src))], + !strconcat("i64.", !strconcat(name, "\t$dst, $src")), + !strconcat("i64.", name), i64Inst>; +} +multiclass BinaryInt<SDNode node, string name, bits<32> i32Inst, + bits<32> i64Inst> { + defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins), + [(set I32:$dst, (node I32:$lhs, I32:$rhs))], + !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")), + !strconcat("i32.", name), i32Inst>; + defm _I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins), + [(set I64:$dst, (node I64:$lhs, I64:$rhs))], + !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")), + !strconcat("i64.", name), i64Inst>; +} +multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32> i64Inst> { + defm _I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs), (outs), (ins), + [(set I32:$dst, (setcc I32:$lhs, I32:$rhs, cond))], + !strconcat("i32.", !strconcat(name, "\t$dst, $lhs, $rhs")), + !strconcat("i32.", name), i32Inst>; + defm _I64 : I<(outs I32:$dst), (ins I64:$lhs, I64:$rhs), (outs), (ins), + [(set I32:$dst, (setcc I64:$lhs, I64:$rhs, cond))], + !strconcat("i64.", !strconcat(name, "\t$dst, $lhs, $rhs")), + !strconcat("i64.", name), i64Inst>; +} // The spaces after the names are for aesthetic purposes only, to make // operands line up vertically after tab expansion. @@ -63,16 +94,12 @@ defm EQZ_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), [(set I32:$dst, (setcc I64:$src, 0, SETEQ))], "i64.eqz \t$dst, $src", "i64.eqz", 0x50>; -} // Defs = [ARGUMENTS] - // Optimize away an explicit mask on a rotate count. def : Pat<(rotl I32:$lhs, (and I32:$rhs, 31)), (ROTL_I32 I32:$lhs, I32:$rhs)>; def : Pat<(rotr I32:$lhs, (and I32:$rhs, 31)), (ROTR_I32 I32:$lhs, I32:$rhs)>; def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>; def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>; -let Defs = [ARGUMENTS] in { - defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond), (outs), (ins), [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))], @@ -82,8 +109,6 @@ defm SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond), [(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))], "i64.select\t$dst, $lhs, $rhs, $cond", "i64.select", 0x1b>; -} // Defs = [ARGUMENTS] - // ISD::SELECT requires its operand to conform to getBooleanContents, but // WebAssembly's select interprets any non-zero value as true, so we can fold // a setne with 0 into a select. @@ -97,3 +122,10 @@ def : Pat<(select (i32 (seteq I32:$cond, 0)), I32:$lhs, I32:$rhs), (SELECT_I32 I32:$rhs, I32:$lhs, I32:$cond)>; def : Pat<(select (i32 (seteq I32:$cond, 0)), I64:$lhs, I64:$rhs), (SELECT_I64 I64:$rhs, I64:$lhs, I32:$cond)>; + +// The legalizer inserts an unnecessary `and 1` to make input conform +// to getBooleanContents, which we can lower away. +def : Pat<(select (i32 (and I32:$cond, 1)), I32:$lhs, I32:$rhs), + (SELECT_I32 I32:$lhs, I32:$rhs, I32:$cond)>; +def : Pat<(select (i32 (and I32:$cond, 1)), I64:$lhs, I64:$rhs), + (SELECT_I64 I64:$lhs, I64:$rhs, I32:$cond)>; |
