Skip to content

Commit

Permalink
riscv64: Add support for the xnor instruction (#7279)
Browse files Browse the repository at this point in the history
* riscv64: Refactor `bnot` lowering rules

Move them to `lower.isle` and clean them up a bit too.

* riscv64: Add support for xnor
  • Loading branch information
alexcrichton authored Oct 18, 2023
1 parent 8e00cc2 commit 8320372
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
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

0 comments on commit 8320372

Please sign in to comment.