Add bitwise ops that invert the second operand.

ARM has all of these as scalar integer instructions. Intel has band_not
in SSE and as a scalar in BMI1.

Add the trivial legalization patterns that use a bnot instruction.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-20 11:14:11 -07:00
parent 014d9a14fe
commit 6ba604125d
4 changed files with 48 additions and 5 deletions

View File

@@ -667,11 +667,9 @@ operating on boolean values, the bitwise operations work as logical operators.
.. autoinst:: bxor
.. autoinst:: bxor_imm
.. autoinst:: bnot
.. todo:: Redundant bitwise operators.
ARM has instructions like ``bic(x,y) = x & ~y``, ``orn(x,y) = x | ~y``, and
``eon(x,y) = x ^ ~y``.
.. autoinst:: band_not
.. autoinst:: bor_not
.. autoinst:: bxor_not
The shift and rotate operations only work on integer types (scalar and vector).
The shift amount does not have to be the same type as the value being shifted.

View File

@@ -28,3 +28,11 @@ ebb0(v0: i32):
; check: $(cst=$V) = iconst.i32 0x3b9a_ca00
; check: $v1 = iadd $v0, $cst
; check: return $v1
function %bitclear(i32, i32) -> i32 {
ebb0(v0: i32, v1: i32):
v2 = band_not v0, v1
; check: bnot
; check: band
return v2
}

View File

@@ -920,6 +920,30 @@ bnot = Instruction(
""",
ins=x, outs=a)
band_not = Instruction(
'band_not', """
Bitwise and not.
Computes `x & ~y`.
""",
ins=(x, y), outs=a)
bor_not = Instruction(
'bor_not', """
Bitwise or not.
Computes `x | ~y`.
""",
ins=(x, y), outs=a)
bxor_not = Instruction(
'bxor_not', """
Bitwise xor not.
Computes `x ^ ~y`.
""",
ins=(x, y), outs=a)
# Bitwise binary ops with immediate arg.
x = Operand('x', iB)
Y = Operand('Y', imm64)

View File

@@ -11,6 +11,7 @@ from .immediates import intcc
from .instructions import iadd, iadd_cout, iadd_cin, iadd_carry, iadd_imm
from .instructions import isub, isub_bin, isub_bout, isub_borrow
from .instructions import band, bor, bxor, isplit, iconcat
from .instructions import bnot, band_not, bor_not, bxor_not
from .instructions import icmp, icmp_imm
from .instructions import iconst, bint
from cdsl.ast import Var
@@ -151,3 +152,15 @@ expand.legalize(
a1 << iconst(y),
a << icmp(cc, x, a1)
))
# Expansions for *_not variants of bitwise ops.
for inst_not, inst in [
(band_not, band),
(bor_not, bor),
(bxor_not, bxor)]:
expand.legalize(
a << inst_not(x, y),
Rtl(
a1 << bnot(y),
a << inst(x, a1)
))