x64: port select to ISLE (#3682)
* x64: port `select` using an FP comparison to ISLE This change includes quite a few interlocking parts, required mainly by the current x64 conventions in ISLE: - it adds a way to emit a `cmove` with multiple OR-ing conditions; because x64 ISLE cannot currently safely emit a comparison followed by several jumps, this adds `MachInst::CmoveOr` and `MachInst::XmmCmoveOr` macro instructions. Unfortunately, these macro instructions hide the multi-instruction sequence in `lower.isle` - to properly keep track of what instructions consume and produce flags, @cfallin added a way to pass around variants of `ConsumesFlags` and `ProducesFlags`--these changes affect all backends - then, to lower the `fcmp + select` CLIF, this change adds several `cmove*_from_values` helpers that perform all of the awkward conversions between `Value`, `ValueReg`, `Reg`, and `Gpr/Xmm`; one upside is that now these lowerings have much-improved documentation explaining why the various `FloatCC` and `CC` choices are made the the way they are. Co-authored-by: Chris Fallin <chris@cfallin.org>
This commit is contained in:
@@ -6,11 +6,11 @@ use generated_code::MInst;
|
||||
use regalloc::Writable;
|
||||
|
||||
// Types that the generated ISLE code uses via `use super::*`.
|
||||
use super::{is_mergeable_load, lower_to_amode, Reg};
|
||||
use super::{is_int_or_ref_ty, is_mergeable_load, lower_to_amode, Reg};
|
||||
use crate::{
|
||||
ir::{
|
||||
immediates::*, types::*, Inst, InstructionData, Opcode, TrapCode, Value, ValueLabel,
|
||||
ValueList,
|
||||
condcodes::FloatCC, immediates::*, types::*, Inst, InstructionData, Opcode, TrapCode,
|
||||
Value, ValueLabel, ValueList,
|
||||
},
|
||||
isa::{
|
||||
settings::Flags,
|
||||
@@ -440,6 +440,32 @@ where
|
||||
fn imm8_to_imm8_gpr(&mut self, imm: u8) -> Imm8Gpr {
|
||||
Imm8Gpr::new(Imm8Reg::Imm8 { imm }).unwrap()
|
||||
}
|
||||
|
||||
fn is_gpr_type(&mut self, ty: Type) -> Option<Type> {
|
||||
if is_int_or_ref_ty(ty) || ty == I128 || ty == B128 {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_xmm_type(&mut self, ty: Type) -> Option<Type> {
|
||||
if ty == F32 || ty == F64 || (ty.is_vector() && ty.bits() == 128) {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_single_register_type(&mut self, ty: Type) -> Option<Type> {
|
||||
if ty != I128 {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since x64 doesn't have 8x16 shifts and we must use a 16x8 shift instead, we
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 9ea75a6f790b5c03
|
||||
src/prelude.isle 73285cd431346d53
|
||||
src/isa/x64/inst.isle 301db31d5f1118ae
|
||||
src/isa/x64/lower.isle cdc94aec26c0bc5b
|
||||
src/prelude.isle 980b300b3ec3e338
|
||||
src/isa/x64/inst.isle ac88a0ae153ed210
|
||||
src/isa/x64/lower.isle 1ebdd4469355e2cf
|
||||
|
||||
1713
cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs
generated
1713
cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user