Skip to content

Commit

Permalink
isle: Migrate f32const/f64const to ISLE
Browse files Browse the repository at this point in the history
This moves the `f32const` and `f64const` instructions from `lower.rs` to
ISLE. I was originally going to add something else but due to the
`isle.rs`'s manual use of `constructor_imm(..)` it necessitated filling
out the `imm` cases for f32/f64 constants, so I figured I'd go ahead and
move these instructions as well.

The special case for 0 constants which use `xorp{s,d}` is preserved from
`lower.rs` today, but a special case isn't added for the all-ones
constant. The comment says to use `cmpeqp{s,d}` but as discovered on
other recent PRs that's not quite sufficient because comparing a
register against itself which happens to be NaN wouldn't work, so
something else will be required (perhaps `pcmpeq` or similar? I figured
I'd defer to later)
  • Loading branch information
alexcrichton committed Nov 16, 2021
1 parent 5d5629d commit 0825bc2
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 212 deletions.
50 changes: 48 additions & 2 deletions cranelift/codegen/src/isa/x64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@
(XmmRmREvex (op Avx512Opcode)
(src1 RegMem)
(src2 Reg)
(dst WritableReg))))
(dst WritableReg))
(GprToXmm (op SseOpcode)
(src RegMem)
(dst WritableReg)
(src_size OperandSize))
))

(type OperandSize extern
(enum Size8
Expand Down Expand Up @@ -568,12 +573,22 @@

;; Helper for emitting immediates.
(decl imm (Type u64) Reg)

;; integer immediates
(rule (imm ty simm64)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(_ Unit (emit (MInst.Imm size simm64 dst))))
(writable_reg_to_reg dst)))

;; f32 immediates
(rule (imm $F32 bits)
(gpr_to_xmm $F32 (SseOpcode.Movd) (RegMem.Reg (imm $I32 bits)) (OperandSize.Size32)))

;; f64 immediates
(rule (imm $F64 bits)
(gpr_to_xmm $F64 (SseOpcode.Movq) (RegMem.Reg (imm $I64 bits)) (OperandSize.Size64)))

(decl nonzero_u64_fits_in_u32 (u64) u64)
(extern extractor nonzero_u64_fits_in_u32 nonzero_u64_fits_in_u32)

Expand All @@ -584,7 +599,7 @@
(_ Unit (emit (MInst.Imm (OperandSize.Size32) x dst))))
(writable_reg_to_reg dst)))

;; Special case for zero immediates: turn them into an `xor r, r`.
;; Special case for integer zero immediates: turn them into an `xor r, r`.
(rule (imm ty 0)
(let ((wr WritableReg (temp_writable_reg ty))
(r Reg (writable_reg_to_reg wr))
Expand All @@ -596,6 +611,30 @@
wr))))
r))

;; Special case for f32 zero immediates to use xorps
(rule (imm $F32 0)
(let ((wr WritableReg (temp_writable_reg $F32))
(r Reg (writable_reg_to_reg wr))
(_ Unit (emit (MInst.XmmRmR (SseOpcode.Xorps)
r
(RegMem.Reg r)
wr))))
r))

;; TODO: use cmpeqps for all 1s

;; Special case for f64 zero immediates to use xorpd
(rule (imm $F64 0)
(let ((wr WritableReg (temp_writable_reg $F64))
(r Reg (writable_reg_to_reg wr))
(_ Unit (emit (MInst.XmmRmR (SseOpcode.Xorpd)
r
(RegMem.Reg r)
wr))))
r))

;; TODO: use cmpeqpd for all 1s

;; Helper for creating `MInst.ShifR` instructions.
(decl shift_r (Type ShiftKind Reg Imm8Reg) Reg)
(rule (shift_r ty kind src1 src2)
Expand Down Expand Up @@ -975,3 +1014,10 @@
(decl mulhi_u (Type Reg RegMem) ValueRegs)
(rule (mulhi_u ty src1 src2)
(mul_hi ty $false src1 src2))

;; Helper for creating `MInst.GprToXmm` instructions.
(decl gpr_to_xmm (Type SseOpcode RegMem OperandSize) Reg)
(rule (gpr_to_xmm ty op src size)
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.GprToXmm op src dst size))))
(writable_reg_to_reg dst)))
10 changes: 10 additions & 0 deletions cranelift/codegen/src/isa/x64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@
(value_regs (imm $B64 1)
(imm $B64 0)))

;;;; Rules for `f32const` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (f32const (u64_from_ieee32 x)))
(value_reg (imm $F32 x)))

;;;; Rules for `f64const` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (f64const (u64_from_ieee64 x)))
(value_reg (imm $F64 x)))

;;;; Rules for `null` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type ty (null)))
Expand Down
26 changes: 10 additions & 16 deletions cranelift/codegen/src/isa/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3364,25 +3364,19 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
}

Opcode::F64const => {
// TODO use cmpeqpd for all 1s.
let value = ctx.get_constant(insn).unwrap();
let dst = get_output_reg(ctx, outputs[0]);
for inst in Inst::gen_constant(dst, value as u128, types::F64, |ty| {
ctx.alloc_tmp(ty).only_reg().unwrap()
}) {
ctx.emit(inst);
}
unreachable!(
"implemented in ISLE: inst = `{}`, type = `{:?}`",
ctx.dfg().display_inst(insn),
ty
);
}

Opcode::F32const => {
// TODO use cmpeqps for all 1s.
let value = ctx.get_constant(insn).unwrap();
let dst = get_output_reg(ctx, outputs[0]);
for inst in Inst::gen_constant(dst, value as u128, types::F32, |ty| {
ctx.alloc_tmp(ty).only_reg().unwrap()
}) {
ctx.emit(inst);
}
unreachable!(
"implemented in ISLE: inst = `{}`, type = `{:?}`",
ctx.dfg().display_inst(insn),
ty
);
}

Opcode::WideningPairwiseDotProductS => {
Expand Down
8 changes: 8 additions & 0 deletions cranelift/codegen/src/isa/x64/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,14 @@ where
None
}
}

fn u64_from_ieee32(&mut self, val: Ieee32) -> u64 {
val.bits().into()
}

fn u64_from_ieee64(&mut self, val: Ieee64) -> u64 {
val.bits()
}
}

#[inline]
Expand Down
Loading

0 comments on commit 0825bc2

Please sign in to comment.