diff --git a/docs/langref.rst b/docs/langref.rst index dde7865486..e7b0cad3d7 100644 --- a/docs/langref.rst +++ b/docs/langref.rst @@ -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. diff --git a/filetests/isa/riscv/expand-i32.cton b/filetests/isa/riscv/expand-i32.cton index 2bffad234c..885d97d309 100644 --- a/filetests/isa/riscv/expand-i32.cton +++ b/filetests/isa/riscv/expand-i32.cton @@ -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 +} diff --git a/lib/cretonne/meta/base/instructions.py b/lib/cretonne/meta/base/instructions.py index 8638e19368..763550a5ee 100644 --- a/lib/cretonne/meta/base/instructions.py +++ b/lib/cretonne/meta/base/instructions.py @@ -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) diff --git a/lib/cretonne/meta/base/legalize.py b/lib/cretonne/meta/base/legalize.py index 058c87f062..91e1e1114a 100644 --- a/lib/cretonne/meta/base/legalize.py +++ b/lib/cretonne/meta/base/legalize.py @@ -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) + ))