Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv64: Add support for the xnor instruction #7279

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,12 @@
(rule (rv_orn rs1 rs2)
(alu_rrr (AluOPRRR.Orn) rs1 rs2))

;; Helper for emitting the `xnor` ("Exclusive NOR") instruction.
;; rd ← ~(rs1 ^ rs2)
(decl rv_xnor (XReg XReg) XReg)
(rule (rv_xnor rs1 rs2)
(alu_rrr (AluOPRRR.Xnor) rs1 rs2))

;; Helper for emitting the `clz` ("Count Leading Zero Bits") instruction.
(decl rv_clz (XReg) XReg)
(rule (rv_clz rs1)
Expand Down Expand Up @@ -2008,23 +2014,6 @@
(rule (select_addi (fits_in_64 ty)) (AluOPRRI.Addi))


(decl gen_bnot (Type ValueRegs) ValueRegs)
(rule 2 (gen_bnot (ty_scalar_float ty) x)
(let ((val FReg (value_regs_get x 0))
(x_val XReg (move_f_to_x val ty))
(inverted XReg (rv_not x_val))
(res FReg (move_x_to_f inverted (float_int_of_same_size ty))))
(value_reg res)))

(rule 1 (gen_bnot $I128 x)
(let ((lo XReg (rv_not (value_regs_get x 0)))
(hi XReg (rv_not (value_regs_get x 1))))
(value_regs lo hi)))

(rule 0 (gen_bnot (ty_int_ref_scalar_64 _) x)
(rv_not (value_regs_get x 0)))


(decl gen_andi (XReg u64) XReg)
(rule 1 (gen_andi x (imm12_from_u64 y))
(rv_andi x y))
Expand Down
19 changes: 16 additions & 3 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -934,12 +934,25 @@
(extern constructor binvi_imm binvi_imm)

;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule 0 (lower (has_type (ty_scalar ty) (bnot x)))
(gen_bnot ty x))

(rule 1 (lower (has_type (ty_vec_fits_in_register ty) (bnot x)))
(rule 0 (lower (has_type (ty_int_ref_scalar_64 _) (bnot x)))
(rv_not x))

(rule 1 (lower (has_type (ty_scalar_float ty) (bnot x)))
(move_x_to_f (rv_not (move_f_to_x x ty)) (float_int_of_same_size ty)))

(rule 2 (lower (has_type $I128 (bnot x)))
(value_regs
(rv_not (value_regs_get x 0))
(rv_not (value_regs_get x 1))))

(rule 3 (lower (has_type (ty_vec_fits_in_register ty) (bnot x)))
(rv_vnot_v x (unmasked) ty))

(rule 4 (lower (has_type (ty_int_ref_scalar_64 _) (bnot (bxor x y))))
(if-let $true (has_zbb))
(rv_xnor x y))

;;;; Rules for `bit_reverse` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 (ty_int ty)) (bitrev x)))
(lower_bit_reverse x ty))
Expand Down
38 changes: 37 additions & 1 deletion cranelift/filetests/filetests/isa/riscv64/wasm/zbb.wat
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,16 @@
(i32.rotr (local.get 0) (i32.const 100)))
(func (export "rori") (param i64) (result i64)
(i64.rotr (local.get 0) (i64.const 40)))
)

(func (export "xnor32_1") (param i32 i32) (result i32)
(i32.xor (i32.xor (local.get 0) (local.get 1)) (i32.const -1)))
(func (export "xnor32_2") (param i32 i32) (result i32)
(i32.xor (i32.const -1) (i32.xor (local.get 0) (local.get 1))))
(func (export "xnor64_1") (param i64 i64) (result i64)
(i64.xor (i64.xor (local.get 0) (local.get 1)) (i64.const -1)))
(func (export "xnor64_2") (param i64 i64) (result i64)
(i64.xor (i64.const -1) (i64.xor (local.get 0) (local.get 1))))
)
;; function u0:0:
;; block0:
;; j label1
Expand Down Expand Up @@ -77,3 +85,31 @@
;; block1:
;; rori a0,a0,40
;; ret
;;
;; function u0:8:
;; block0:
;; j label1
;; block1:
;; xnor a0,a0,a1
;; ret
;;
;; function u0:9:
;; block0:
;; j label1
;; block1:
;; xnor a0,a0,a1
;; ret
;;
;; function u0:10:
;; block0:
;; j label1
;; block1:
;; xnor a0,a0,a1
;; ret
;;
;; function u0:11:
;; block0:
;; j label1
;; block1:
;; xnor a0,a0,a1
;; ret