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: Move rev8 instruction to ISLE #7319

Merged
merged 1 commit into from
Oct 21, 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
53 changes: 1 addition & 52 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,7 @@
(tmp WritableReg)
(rs Reg)
(ty Type))
;; Byte-reverse register
(Rev8
(rs Reg)
(step WritableReg)
(tmp WritableReg)
(rd WritableReg))
;;

(Brev8
(rs Reg)
(ty Type)
Expand Down Expand Up @@ -2035,34 +2029,6 @@
(rule 0 (gen_or (fits_in_64 _) x y)
(rv_or (value_regs_get x 0) (value_regs_get y 0)))

(decl lower_bit_reverse (Reg Type) Reg)

(rule
(lower_bit_reverse r $I8)
(gen_brev8 r $I8))

(rule
(lower_bit_reverse r $I16)
(let
((tmp XReg (gen_brev8 r $I16))
(tmp2 XReg (gen_rev8 tmp))
(result XReg (rv_srli tmp2 (imm12_const 48))))
result))

(rule
(lower_bit_reverse r $I32)
(let
((tmp XReg (gen_brev8 r $I32))
(tmp2 XReg (gen_rev8 tmp))
(result XReg (rv_srli tmp2 (imm12_const 32))))
result))

(rule
(lower_bit_reverse r $I64)
(let
((tmp XReg (gen_rev8 r)))
(gen_brev8 tmp $I64)))


(decl lower_ctz (Type Reg) Reg)
(rule (lower_ctz ty x)
Expand Down Expand Up @@ -2728,23 +2694,6 @@
(rule (float_int_of_same_size $F64) $I64)


(decl gen_rev8 (XReg) XReg)
(rule 1
(gen_rev8 rs)
(if-let $true (has_zbb))
(rv_rev8 rs))

(rule
(gen_rev8 rs)
(if-let $false (has_zbb))
(let
((rd WritableXReg (temp_writable_xreg))
(tmp WritableXReg (temp_writable_xreg))
(step WritableXReg (temp_writable_xreg))
(_ Unit (emit (MInst.Rev8 rs step tmp rd))))
(writable_reg_to_reg rd)))


(decl gen_brev8 (Reg Type) Reg)
(rule 1
(gen_brev8 rs _)
Expand Down
74 changes: 0 additions & 74 deletions cranelift/codegen/src/isa/riscv64/inst/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ impl Inst {
| Inst::DummyUse { .. }
| Inst::FloatRound { .. }
| Inst::Popcnt { .. }
| Inst::Rev8 { .. }
| Inst::Cltz { .. }
| Inst::Brev8 { .. }
| Inst::StackProbeLoop { .. } => None,
Expand Down Expand Up @@ -2535,71 +2534,6 @@ impl Inst {
}
sink.bind_label(label_done, &mut state.ctrl_plane);
}
&Inst::Rev8 { rs, rd, tmp, step } => {
// init.
Inst::gen_move(rd, zero_reg(), I64).emit(&[], sink, emit_info, state);
Inst::gen_move(tmp, rs, I64).emit(&[], sink, emit_info, state);
// load 56 to step.
Inst::load_imm12(step, Imm12::from_i16(56)).emit(&[], sink, emit_info, state);
let label_done = sink.get_label();
let label_loop = sink.get_label();
sink.bind_label(label_loop, &mut state.ctrl_plane);
Inst::CondBr {
taken: CondBrTarget::Label(label_done),
not_taken: CondBrTarget::Fallthrough,
kind: IntegerCompare {
kind: IntCC::SignedLessThan,
rs1: step.to_reg(),
rs2: zero_reg(),
},
}
.emit(&[], sink, emit_info, state);
Inst::AluRRImm12 {
alu_op: AluOPRRI::Andi,
rd: writable_spilltmp_reg(),
rs: tmp.to_reg(),
imm12: Imm12::from_i16(255),
}
.emit(&[], sink, emit_info, state);
Inst::AluRRR {
alu_op: AluOPRRR::Sll,
rd: writable_spilltmp_reg(),
rs1: spilltmp_reg(),
rs2: step.to_reg(),
}
.emit(&[], sink, emit_info, state);

Inst::AluRRR {
alu_op: AluOPRRR::Or,
rd: rd,
rs1: rd.to_reg(),
rs2: spilltmp_reg(),
}
.emit(&[], sink, emit_info, state);

{
// reset step
Inst::AluRRImm12 {
alu_op: AluOPRRI::Addi,
rd: step,
rs: step.to_reg(),
imm12: Imm12::from_i16(-8),
}
.emit(&[], sink, emit_info, state);
//reset tmp.
Inst::AluRRImm12 {
alu_op: AluOPRRI::Srli,
rd: tmp,
rs: tmp.to_reg(),
imm12: Imm12::from_i16(8),
}
.emit(&[], sink, emit_info, state);
// loop.
Inst::gen_jump(label_loop).emit(&[], sink, emit_info, state);
}

sink.bind_label(label_done, &mut state.ctrl_plane);
}
&Inst::Cltz {
sum,
tmp,
Expand Down Expand Up @@ -3447,14 +3381,6 @@ impl Inst {
sum: allocs.next_writable(sum),
ty,
},

Inst::Rev8 { rs, rd, tmp, step } => Inst::Rev8 {
rs: allocs.next(rs),
tmp: allocs.next_writable(tmp),
step: allocs.next_writable(step),
rd: allocs.next_writable(rd),
},

Inst::Cltz {
sum,
tmp,
Expand Down
13 changes: 0 additions & 13 deletions cranelift/codegen/src/isa/riscv64/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,12 +610,6 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
collector.reg_early_def(step);
collector.reg_early_def(sum);
}
&Inst::Rev8 { rs, rd, tmp, step } => {
collector.reg_use(rs);
collector.reg_early_def(tmp);
collector.reg_early_def(step);
collector.reg_early_def(rd);
}
&Inst::Cltz {
sum, step, tmp, rs, ..
} => {
Expand Down Expand Up @@ -1187,13 +1181,6 @@ impl Inst {
let sum = format_reg(sum.to_reg(), allocs);
format!("popcnt {},{}##ty={} tmp={} step={}", sum, rs, ty, tmp, step)
}
&Inst::Rev8 { rs, rd, tmp, step } => {
let rs = format_reg(rs, allocs);
let tmp = format_reg(tmp.to_reg(), allocs);
let step = format_reg(step.to_reg(), allocs);
let rd = format_reg(rd.to_reg(), allocs);
format!("rev8 {},{}##step={} tmp={}", rd, rs, step, tmp)
}
&Inst::Cltz {
sum,
step,
Expand Down
55 changes: 33 additions & 22 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -954,14 +954,30 @@
(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))

(rule 0 (lower (has_type (ty_int_ref_scalar_64 ty) (bitrev x)))
(gen_bitrev ty x))

(rule 1 (lower (has_type $I128 (bitrev x)))
(let ((val ValueRegs x)
(lo_rev XReg (lower_bit_reverse (value_regs_get val 0) $I64))
(hi_rev XReg (lower_bit_reverse (value_regs_get val 1) $I64)))
(value_regs hi_rev lo_rev)))
(value_regs
(gen_bitrev $I64 (value_regs_get x 1))
(gen_bitrev $I64 (value_regs_get x 0))))


;; Constructs a sequence of instructions that reverse all bits in `x` up to
;; the given type width.
(decl gen_bitrev (Type XReg) XReg)

(rule 0 (gen_bitrev (ty_16_or_32 (ty_int ty)) x)
(if-let shift_amt (u64_to_imm12 (u64_sub 64 (ty_bits ty))))
(rv_srli (gen_bitrev $I64 x) shift_amt))

(rule 1 (gen_bitrev $I8 x)
(gen_brev8 x $I8))

(rule 1 (gen_bitrev $I64 x)
(gen_brev8 (gen_bswap $I64 x) $I64))


;;;; Rules for `bswap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand All @@ -973,22 +989,8 @@
(gen_bswap $I64 (value_regs_get x 1))
(gen_bswap $I64 (value_regs_get x 0))))

(rule 3 (lower (has_type (fits_in_32 ty) (bswap x)))
(if-let $true (has_zbb))
(if-let shift_amt (u64_to_imm12 (u64_sub 64 (ty_bits ty))))
(rv_srli (rv_rev8 x) shift_amt))

(rule 4 (lower (has_type $I64 (bswap x)))
(if-let $true (has_zbb))
(rv_rev8 x))

(rule 5 (lower (has_type $I128 (bswap x)))
(if-let $true (has_zbb))
(value_regs
(rv_rev8 (value_regs_get x 1))
(rv_rev8 (value_regs_get x 0))))

;; Helper to generate a fallback byte-swap sequence when `zbb` isn't available.
;; Builds a sequence of instructions that swaps the bytes in `x` up to the given
;; type width.
(decl gen_bswap (Type XReg) XReg)

;; This is only here to make the rule below work. bswap.i8 isn't valid
Expand All @@ -1012,6 +1014,15 @@
(bot XReg (rv_srli bot_shifted_left shift)))
(rv_or top bot)))

(rule 2 (gen_bswap (ty_16_or_32 (ty_int ty)) x)
(if-let $true (has_zbb))
(if-let shift_amt (u64_to_imm12 (u64_sub 64 (ty_bits ty))))
(rv_srli (rv_rev8 x) shift_amt))

(rule 3 (gen_bswap $I64 x)
(if-let $true (has_zbb))
(rv_rev8 x))

;;;; Rules for `ctz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (has_type (fits_in_64 ty) (ctz x)))
(lower_ctz ty x))
Expand Down
9 changes: 9 additions & 0 deletions cranelift/codegen/src/isle_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,15 @@ macro_rules! isle_common_prelude_methods {
}
}

#[inline]
fn ty_16_or_32(&mut self, ty: Type) -> Option<Type> {
if ty.bits() == 16 || ty.bits() == 32 {
Some(ty)
} else {
None
}
}

#[inline]
fn int_fits_in_32(&mut self, ty: Type) -> Option<Type> {
match ty {
Expand Down
4 changes: 4 additions & 0 deletions cranelift/codegen/src/prelude.isle
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@
(decl ty_8_or_16 (Type) Type)
(extern extractor ty_8_or_16 ty_8_or_16)

;; An extractor that matches 16- and 32-bit types only.
(decl ty_16_or_32 (Type) Type)
(extern extractor ty_16_or_32 ty_16_or_32)

;; An extractor that matches int types that fit in 32 bits.
(decl int_fits_in_32 (Type) Type)
(extern extractor int_fits_in_32 int_fits_in_32)
Expand Down
Loading