Skip to content
Draft
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
3 changes: 2 additions & 1 deletion cranelift/codegen/meta/src/cdsl/formats.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::cdsl::operands::OperandKind;
use crate::display_join::DisplayJoinedVecExt;
use std::fmt;
use std::rc::Rc;

Expand Down Expand Up @@ -66,7 +67,7 @@ impl fmt::Display for InstructionFormat {
.iter()
.map(|field| format!("{}: {}", field.member, field.kind.rust_type))
.collect::<Vec<_>>()
.join(", ");
.display_join(", ");
fmt.write_fmt(format_args!(
"{}(imms=({}), vals={}, blocks={}, raw_blocks={})",
self.name,
Expand Down
10 changes: 6 additions & 4 deletions cranelift/codegen/meta/src/cdsl/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::cdsl::formats::InstructionFormat;
use crate::cdsl::operands::Operand;
use crate::cdsl::typevar::TypeVar;

use crate::display_join::DisplayJoinedVecExt;

pub(crate) type AllInstructions = Vec<Instruction>;

pub(crate) struct InstructionGroupBuilder<'all_inst> {
Expand Down Expand Up @@ -102,8 +104,8 @@ impl fmt::Display for InstructionContent {
.iter()
.map(|op| op.name)
.collect::<Vec<_>>()
.join(", ");
fmt.write_str(&operands_out)?;
.display_join(", ");
operands_out.fmt(fmt)?;
fmt.write_str(" = ")?;
}

Expand All @@ -115,9 +117,9 @@ impl fmt::Display for InstructionContent {
.iter()
.map(|op| op.name)
.collect::<Vec<_>>()
.join(", ");
.display_join(", ");
fmt.write_str(" ")?;
fmt.write_str(&operands_in)?;
operands_in.fmt(fmt)?;
}

Ok(())
Expand Down
12 changes: 7 additions & 5 deletions cranelift/codegen/meta/src/cdsl/typevar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::hash;
use std::ops;
use std::rc::Rc;

use crate::display_join::DisplayJoinedVecExt;

use crate::cdsl::types::{LaneType, ValueType};

const MAX_LANES: u16 = 256;
Expand Down Expand Up @@ -532,29 +534,29 @@ impl fmt::Debug for TypeSet {
if !self.lanes.is_empty() {
subsets.push(format!(
"lanes={{{}}}",
Vec::from_iter(self.lanes.iter().map(|x| x.to_string())).join(", ")
Vec::from_iter(self.lanes.iter().map(|x| x.to_string())).display_join(", ")
));
}
if !self.dynamic_lanes.is_empty() {
subsets.push(format!(
"dynamic_lanes={{{}}}",
Vec::from_iter(self.dynamic_lanes.iter().map(|x| x.to_string())).join(", ")
Vec::from_iter(self.dynamic_lanes.iter().map(|x| x.to_string())).display_join(", ")
));
}
if !self.ints.is_empty() {
subsets.push(format!(
"ints={{{}}}",
Vec::from_iter(self.ints.iter().map(|x| x.to_string())).join(", ")
Vec::from_iter(self.ints.iter().map(|x| x.to_string())).display_join(", ")
));
}
if !self.floats.is_empty() {
subsets.push(format!(
"floats={{{}}}",
Vec::from_iter(self.floats.iter().map(|x| x.to_string())).join(", ")
Vec::from_iter(self.floats.iter().map(|x| x.to_string())).display_join(", ")
));
}

write!(fmt, "{})", subsets.join(", "))?;
write!(fmt, "{})", subsets.display_join(", "))?;
Ok(())
}
}
Expand Down
35 changes: 35 additions & 0 deletions cranelift/codegen/meta/src/display_join.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/// Joins strings, just like `.join(" ")` but with [`core::fmt::Display`]
pub(crate) struct DisplayJoined<'a, S: AsRef<str>>(pub &'static str, pub &'a [S]);

impl<'a, S: AsRef<str>> core::fmt::Display for DisplayJoined<'a, S> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut sep = false;
for s in self.1 {
if sep {
f.write_str(self.0)?;
}
sep = true;
f.write_str(s.as_ref())?;
}
Ok(())
}
}

/// Joins strings, just like `.join(" ")` but with [`core::fmt::Display`]
pub(crate) struct DisplayJoinedVec<S: AsRef<str>>(pub &'static str, pub Vec<S>);

impl<S: AsRef<str>> core::fmt::Display for DisplayJoinedVec<S> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
DisplayJoined(self.0, &self.1).fmt(f)
}
}

pub(crate) trait DisplayJoinedVecExt<S: AsRef<str>> {
/// Joins strings, just like `.join(" ")` but with [`core::fmt::Display`]
fn display_join(self, sep: &'static str) -> DisplayJoinedVec<S>;
}
impl<S: AsRef<str>> DisplayJoinedVecExt<S> for Vec<S> {
fn display_join(self, sep: &'static str) -> DisplayJoinedVec<S> {
DisplayJoinedVec(sep, self)
}
}
60 changes: 33 additions & 27 deletions cranelift/codegen/meta/src/gen_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use cranelift_assembler_x64_meta::dsl::{
};
use cranelift_srcgen::{Formatter, fmtln};

use crate::display_join::DisplayJoinedVecExt;

/// This factors out use of the assembler crate name.
const ASM: &str = "cranelift_assembler_x64";

Expand Down Expand Up @@ -110,17 +112,16 @@ fn generate_macro_inst_fn(f: &mut Formatter, inst: &Inst) {
.iter()
.filter(|o| o.mutability.is_write())
.collect::<Vec<_>>();
let rust_params = operands
let mut rust_params = operands
.iter()
.filter(|o| is_raw_operand_param(o))
.map(|o| format!("{}: {}", o.location, rust_param_raw(o)))
.chain(if inst.has_trap {
Some(format!("trap: &TrapCode"))
} else {
None
})
.collect::<Vec<_>>()
.join(", ");
.collect::<Vec<_>>();
if inst.has_trap {
rust_params.push("trap: &TrapCode".to_string());
}
let rust_params = rust_params.display_join(", ");

f.add_block(
&format!("fn x64_{struct_name}_raw(&mut self, {rust_params}) -> AssemblerOutputs"),
|f| {
Expand All @@ -137,7 +138,7 @@ fn generate_macro_inst_fn(f: &mut Formatter, inst: &Inst) {
if inst.has_trap {
args.push(format!("{ASM}::TrapCode(trap.as_raw())"));
}
let args = args.join(", ");
let args = args.display_join(", ");
f.empty_line();

f.comment("Build the instruction.");
Expand Down Expand Up @@ -179,12 +180,12 @@ fn generate_macro_inst_fn(f: &mut Formatter, inst: &Inst) {
}
RegMem(rm) => {
let (ty, var) = ty_var_of_reg(rm);
f.add_block(&format!("match {rm}"), |f| {
f.add_block(&format!("{ASM}::{ty}Mem::{ty}(reg) => "), |f| {
f.add_block(format_args!("match {rm}"), |f| {
f.add_block(format_args!("{ASM}::{ty}Mem::{ty}(reg) => "), |f| {
fmtln!(f, "let {var} = reg.{};", access_reg(op));
fmtln!(f, "AssemblerOutputs::Ret{ty} {{ inst, {var} }} ");
});
f.add_block(&format!("{ASM}::{ty}Mem::Mem(_) => "), |f| {
f.add_block(format_args!("{ASM}::{ty}Mem::Mem(_) => "), |f| {
fmtln!(f, "AssemblerOutputs::SideEffect {{ inst }} ");
});
});
Expand Down Expand Up @@ -548,12 +549,12 @@ fn generate_isle_inst_decls(f: &mut Formatter, inst: &Inst) {
.iter()
.filter(|o| is_raw_operand_param(o))
.collect::<Vec<_>>();
let raw_param_tys = params
.iter()
.map(|o| isle_param_raw(o))
.chain(trap_type.clone())
.collect::<Vec<_>>()
.join(" ");
let mut raw_param_tys = params.iter().map(|o| isle_param_raw(o)).collect::<Vec<_>>();
if let Some(trap_type) = &trap_type {
raw_param_tys.push(trap_type.clone());
}
let raw_param_tys = raw_param_tys.display_join(" ");

fmtln!(f, "(decl {raw_name} ({raw_param_tys}) AssemblerOutputs)");
fmtln!(f, "(extern constructor {raw_name} {raw_name})");

Expand Down Expand Up @@ -584,18 +585,22 @@ fn generate_isle_inst_decls(f: &mut Formatter, inst: &Inst) {
}
}
assert!(implicit_params.len() <= 1);
let param_tys = explicit_params
let mut param_tys = explicit_params
.iter()
.map(|o| isle_param_for_ctor(o, ctor))
.chain(trap_type.clone())
.collect::<Vec<_>>()
.join(" ");
let param_names = explicit_params
.collect::<Vec<_>>();
if let Some(trap_type) = &trap_type {
param_tys.push(trap_type.clone());
}
let param_tys = param_tys.display_join(" ");
let mut param_names = explicit_params
.iter()
.map(|o| o.location.to_string())
.chain(trap_name.clone())
.collect::<Vec<_>>()
.join(" ");
.collect::<Vec<_>>();
if let Some(trap_name) = &trap_name {
param_names.push(trap_name.clone());
}
let param_names = param_names.display_join(" ");
let convert = ctor.conversion_constructor();

// Generate implicit parameters to the `*_raw` constructor. Currently
Expand All @@ -619,7 +624,7 @@ fn generate_isle_inst_decls(f: &mut Formatter, inst: &Inst) {
}
})
.collect::<Vec<_>>()
.join(" ");
.display_join(" ");

fmtln!(f, "(decl {rule_name} ({param_tys}) {result_ty})");
fmtln!(
Expand All @@ -638,6 +643,7 @@ fn generate_isle_inst_decls(f: &mut Formatter, inst: &Inst) {
.iter()
.any(|o| matches!(o.location.reg_class(), Some(RegClass::Xmm)))
);
let param_tys = param_tys.to_string();
let param_tys = if alternate.feature == Feature::avx {
param_tys.replace("Aligned", "")
} else {
Expand Down
Loading
Loading