Skip to content
Closed
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
27 changes: 23 additions & 4 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,12 @@
(rule (rv_andi rs1 imm)
(alu_rr_imm12 (AluOPRRI.Andi) rs1 imm))

;; Helper for emitting the `slt` ("Set Less Than") instruction.
;; rd ← rs1 < rs2
(decl rv_slt (XReg XReg) XReg)
(rule (rv_slt rs1 rs2)
(alu_rrr (AluOPRRR.Slt) rs1 rs2))

;; Helper for emitting the `sltu` ("Set Less Than Unsigned") instruction.
;; rd ← rs1 < rs2
(decl rv_sltu (XReg XReg) XReg)
Expand All @@ -1222,12 +1228,28 @@
(rule (rv_snez rs1)
(rv_sltu (zero_reg) rs1))

;; Helper for emiting the `slti` ("Set Less Than Immediate") instruction.
;; rd ← rs1 < imm
(decl rv_slti (XReg Imm12) XReg)
(rule (rv_slti rs1 imm)
(alu_rr_imm12 (AluOPRRI.Slti) rs1 imm))

;; Helper for emiting the `sltiu` ("Set Less Than Immediate Unsigned") instruction.
;; rd ← rs1 < imm
(decl rv_sltiu (XReg Imm12) XReg)
(rule (rv_sltiu rs1 imm)
(alu_rr_imm12 (AluOPRRI.SltiU) rs1 imm))

;; Helper for emitting the `sltz` instruction.
;; This instruction is a mnemonic for `slt rd, rs, zero`.
(decl rv_sltz (XReg) XReg)
(rule (rv_sltz rs) (rv_slt rs (zero_reg)))

;; Helper for emitting the `sgtz` instruction.
;; This instruction is a mnemonic for `slt rd, zero, rs`.
(decl rv_sgtz (XReg) XReg)
(rule (rv_sgtz rs) (rv_slt (zero_reg) rs))

;; Helper for emitting the `seqz` instruction.
;; This instruction is a mnemonic for `sltiu rd, rs, 1`.
(decl rv_seqz (XReg) XReg)
Expand Down Expand Up @@ -1718,9 +1740,6 @@
(decl imm_from_bits (u64) Imm12)
(extern constructor imm_from_bits imm_from_bits)

(decl imm_from_neg_bits (i64) Imm12)
(extern constructor imm_from_neg_bits imm_from_neg_bits)

(decl imm12_const_add (i32 i32) Imm12)
(extern constructor imm12_const_add imm12_const_add)

Expand Down Expand Up @@ -3035,7 +3054,7 @@
(extern constructor sp_reg sp_reg)

;; Helper for creating the zero register.
(decl zero_reg () Reg)
(decl zero_reg () XReg)
(extern constructor zero_reg zero_reg)

(decl value_regs_zero () ValueRegs)
Expand Down
85 changes: 84 additions & 1 deletion cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1603,10 +1603,93 @@
(rule 0 (lower (icmp cc x @ (value_type (ty_int ty)) y))
(lower_icmp cc x y ty))

(rule 1 (lower (icmp cc x @ (value_type (ty_vec_fits_in_register ty)) y))
(rule 1 (lower (icmp cc x @ (value_type (ty_int_ref_scalar_64 _)) y))
(scalar_icmp cc x y))

;; try to put constants on the right hand side of `scalar_icmp` to avoid
;; duplication of those rules
(rule 2 (lower (icmp cc x @ (iconst _) y @ (value_type (ty_int_ref_scalar_64 _))))
(scalar_icmp (intcc_swap_args cc) y x))

(rule 3 (lower (icmp cc x @ (value_type (ty_vec_fits_in_register ty)) y))
(gen_expand_mask ty (gen_icmp_mask ty cc x y)))


;; Helper to compare just two scalars. Callers should try to put constants on
;; the right-hand side.
(decl scalar_icmp (IntCC Value Value) XReg)
(rule 0 (scalar_icmp (IntCC.Equal) x y)
(rv_seqz (rv_xor x y)))

;; x == y <=> x - y == 0
(rule 1 (scalar_icmp (IntCC.Equal) x (i64_from_iconst y))
(if-let (imm12_from_i64 imm) (i64_neg y))
(rv_seqz (rv_addi x imm)))

(rule 2 (scalar_icmp (IntCC.Equal) x (u64_from_iconst 0))
(rv_seqz x))

(rule 0 (scalar_icmp (IntCC.NotEqual) x y)
(rv_snez (rv_xor x y)))

;; x != y <=> x - y != 0
(rule 1 (scalar_icmp (IntCC.NotEqual) x (i64_from_iconst y))
(if-let (imm12_from_i64 imm) (i64_neg y))
(rv_snez (rv_addi x imm)))

(rule 2 (scalar_icmp (IntCC.NotEqual) x (u64_from_iconst 0))
(rv_snez x))

;; x != -1 <=> (unsigned) x < UINT_MAX
(rule 3 (scalar_icmp (IntCC.NotEqual) x (i64_from_iconst -1))
(rv_sltiu x (imm12_const -1)))

(rule 0 (scalar_icmp (IntCC.SignedLessThan) x y)
(rv_slt x y))

(rule 1 (scalar_icmp (IntCC.SignedLessThan) x (imm12_from_value y))
(rv_slti x y))

(rule 2 (scalar_icmp (IntCC.SignedLessThan) x (u64_from_iconst 0))
(rv_sltz x))

(rule 0 (scalar_icmp (IntCC.UnsignedLessThan) x y)
(rv_sltu x y))

(rule 1 (scalar_icmp (IntCC.UnsignedLessThan) x (imm12_from_value y))
(rv_sltiu x y))

;; x < 1 <=> x == 0
(rule 2 (scalar_icmp (IntCC.UnsignedLessThan) x (u64_from_iconst 1))
(rv_seqz x))

;; x > y <=> y < x
(rule 0 (scalar_icmp (IntCC.SignedGreaterThan) x y)
(rv_slt y x))

(rule 1 (scalar_icmp (IntCC.SignedGreaterThan) x (u64_from_iconst 0))
(rv_sgtz x))

;; x > y <=> y < x
(rule 0 (scalar_icmp (IntCC.UnsignedGreaterThan) x y)
(rv_sltu y x))

;; x > 0 <=> x != 0
(rule 1 (scalar_icmp (IntCC.UnsignedGreaterThan) x (u64_from_iconst 0))
(rv_snez x))

;; for remaining variants with have a "OrEqual" condition code invert the
;; condition and invert the result.
(rule 0 (scalar_icmp cc @ (IntCC.SignedGreaterThanOrEqual) x y)
(rv_xori (scalar_icmp (intcc_complement cc) x y) (imm12_const 1)))
(rule 0 (scalar_icmp cc @ (IntCC.UnsignedGreaterThanOrEqual) x y)
(rv_xori (scalar_icmp (intcc_complement cc) x y) (imm12_const 1)))
(rule 0 (scalar_icmp cc @ (IntCC.SignedLessThanOrEqual) x y)
(rv_xori (scalar_icmp (intcc_complement cc) x y) (imm12_const 1)))
(rule 0 (scalar_icmp cc @ (IntCC.UnsignedLessThanOrEqual) x y)
(rv_xori (scalar_icmp (intcc_complement cc) x y) (imm12_const 1)))


;;;;; Rules for `fcmp`;;;;;;;;;
(rule 0 (lower (fcmp cc x @ (value_type (ty_scalar_float ty)) y))
(cmp_value (emit_fcmp cc ty x y)))
Expand Down
12 changes: 4 additions & 8 deletions cranelift/codegen/src/isa/riscv64/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ impl generated_code::Context for RV64IsleContext<'_, '_, MInst, Riscv64Backend>
fn int_zero_reg(&mut self, ty: Type) -> ValueRegs {
assert!(ty.is_int(), "{:?}", ty);
if ty.bits() == 128 {
ValueRegs::two(self.zero_reg(), self.zero_reg())
ValueRegs::two(self.zero_reg().to_reg(), self.zero_reg().to_reg())
} else {
ValueRegs::one(self.zero_reg())
ValueRegs::one(self.zero_reg().to_reg())
}
}

Expand Down Expand Up @@ -343,17 +343,13 @@ impl generated_code::Context for RV64IsleContext<'_, '_, MInst, Riscv64Backend>
writable_zero_reg()
}
#[inline]
fn zero_reg(&mut self) -> Reg {
zero_reg()
fn zero_reg(&mut self) -> XReg {
XReg::new(zero_reg()).unwrap()
}
#[inline]
fn imm_from_bits(&mut self, val: u64) -> Imm12 {
Imm12::maybe_from_u64(val).unwrap()
}
#[inline]
fn imm_from_neg_bits(&mut self, val: i64) -> Imm12 {
Imm12::maybe_from_i64(val).unwrap()
}

fn gen_default_frm(&mut self) -> OptionFloatRoundingMode {
None
Expand Down
9 changes: 4 additions & 5 deletions cranelift/filetests/filetests/isa/riscv64/condbr.clif
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ block0(v0: i64, v1: i64):

; VCode:
; block0:
; eq a0,a0,a1##ty=i64
; xor a3,a0,a1
; seqz a0,a3
; ret
;
; Disassembled:
; block0: ; offset 0x0
; bne a0, a1, 0xc
; addi a0, zero, 1
; j 8
; mv a0, zero
; xor a3, a0, a1
; seqz a0, a3
; ret

function %icmp_eq_i128(i128, i128) -> i8 {
Expand Down
15 changes: 4 additions & 11 deletions cranelift/filetests/filetests/isa/riscv64/condops.clif
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,14 @@ block0(v0: i8):

; VCode:
; block0:
; li a5,42
; andi a3,a0,255
; andi a5,a5,255
; eq a0,a3,a5##ty=i8
; addi a2,a0,-42
; seqz a0,a2
; ret
;
; Disassembled:
; block0: ; offset 0x0
; addi a5, zero, 0x2a
; andi a3, a0, 0xff
; andi a5, a5, 0xff
; bne a3, a5, 0xc
; addi a0, zero, 1
; j 8
; mv a0, zero
; addi a2, a0, -0x2a
; seqz a0, a2
; ret

function %h(i8, i8, i8) -> i8 {
Expand Down
Loading