Skip to content

Commit

Permalink
Ran out of steam, giving up for now
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Feb 17, 2025
1 parent cb84d74 commit 8344547
Show file tree
Hide file tree
Showing 13 changed files with 319 additions and 49 deletions.
2 changes: 1 addition & 1 deletion cranelift/assembler-x64/meta/src/dsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod format;

pub use encoding::{rex, vex, Encoding, LegacyPrefix, Rex};
pub use features::{Feature, Features, ALL_FEATURES};
pub use format::{fmt, r, rw, sxl, sxq, sxw};
pub use format::{fmt, r, rw, sxl, sxq, sxw, w};
pub use format::{Extension, Format, Location, Mutability, Operand, OperandKind};

/// Abbreviated constructor for an x64 instruction.
Expand Down
73 changes: 65 additions & 8 deletions cranelift/assembler-x64/meta/src/dsl/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub fn rw(location: Location) -> Operand {
location,
mutability: Mutability::ReadWrite,
extension: Extension::default(),
disas: true,
}
}

Expand All @@ -47,6 +48,18 @@ pub fn r(location: Location) -> Operand {
location,
mutability: Mutability::Read,
extension: Extension::None,
disas: true,
}
}

/// An abbreviated constructor for a "write" operand.
#[must_use]
pub fn w(location: Location) -> Operand {
Operand {
location,
mutability: Mutability::Write,
extension: Extension::None,
disas: true,
}
}

Expand All @@ -63,6 +76,7 @@ pub fn sxq(location: Location) -> Operand {
location,
mutability: Mutability::Read,
extension: Extension::SignExtendQuad,
disas: true,
}
}

Expand All @@ -79,6 +93,7 @@ pub fn sxl(location: Location) -> Operand {
location,
mutability: Mutability::Read,
extension: Extension::SignExtendLong,
disas: true,
}
}

Expand All @@ -95,6 +110,7 @@ pub fn sxw(location: Location) -> Operand {
location,
mutability: Mutability::Read,
extension: Extension::SignExtendWord,
disas: true,
}
}

Expand Down Expand Up @@ -166,11 +182,20 @@ pub struct Operand {
pub mutability: Mutability,
/// Some operands are sign- or zero-extended.
pub extension: Extension,
/// TODO
pub disas: bool,
}

impl Operand {
/// TODO
pub fn disas(self, disas: bool) -> Operand {
Operand { disas, ..self }
}
}

impl core::fmt::Display for Operand {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let Self { location, mutability, extension } = self;
let Self { location, mutability, extension, disas: _ } = self;
write!(f, "{location}")?;
let has_default_mutability = matches!(mutability, Mutability::Read);
let has_default_extension = matches!(extension, Extension::None);
Expand All @@ -188,7 +213,7 @@ impl From<Location> for Operand {
fn from(location: Location) -> Self {
let mutability = Mutability::default();
let extension = Extension::default();
Self { location, mutability, extension }
Self { location, mutability, extension, disas: true }
}
}

Expand All @@ -203,6 +228,10 @@ pub enum Location {

cl,

dx,
edx,
rdx,

imm8,
imm16,
imm32,
Expand All @@ -225,9 +254,9 @@ impl Location {
use Location::*;
match self {
al | cl | imm8 | r8 | rm8 => 8,
ax | imm16 | r16 | rm16 => 16,
eax | imm32 | r32 | rm32 => 32,
rax | r64 | rm64 => 64,
ax | dx | imm16 | r16 | rm16 => 16,
eax | edx | imm32 | r32 | rm32 => 32,
rax | rdx | r64 | rm64 => 64,
}
}

Expand All @@ -242,7 +271,7 @@ impl Location {
pub fn uses_memory(&self) -> bool {
use Location::*;
match self {
al | cl | ax | eax | rax | imm8 | imm16 | imm32 | r8 | r16 | r32 | r64 => false,
al | cl | ax | eax | rax | dx | edx | rdx | imm8 | imm16 | imm32 | r8 | r16 | r32 | r64 => false,
rm8 | rm16 | rm32 | rm64 => true,
}
}
Expand All @@ -254,7 +283,9 @@ impl Location {
use Location::*;
match self {
imm8 | imm16 | imm32 => false,
al | ax | eax | rax | cl | r8 | r16 | r32 | r64 | rm8 | rm16 | rm32 | rm64 => true,
al | ax | eax | rax | cl | dx | edx | rdx | r8 | r16 | r32 | r64 | rm8 | rm16 | rm32 | rm64 => {
true
}
}
}

Expand All @@ -263,7 +294,7 @@ impl Location {
pub fn kind(&self) -> OperandKind {
use Location::*;
match self {
al | ax | eax | rax | cl => OperandKind::FixedReg(*self),
al | ax | eax | rax | cl | dx | edx | rdx => OperandKind::FixedReg(*self),
imm8 | imm16 | imm32 => OperandKind::Imm(*self),
r8 | r16 | r32 | r64 => OperandKind::Reg(*self),
rm8 | rm16 | rm32 | rm64 => OperandKind::RegMem(*self),
Expand All @@ -282,6 +313,10 @@ impl core::fmt::Display for Location {

cl => write!(f, "cl"),

dx => write!(f, "dx"),
edx => write!(f, "edx"),
rdx => write!(f, "rdx"),

imm8 => write!(f, "imm8"),
imm16 => write!(f, "imm16"),
imm32 => write!(f, "imm32"),
Expand Down Expand Up @@ -324,6 +359,7 @@ pub enum OperandKind {
pub enum Mutability {
Read,
ReadWrite,
Write,
}

impl Default for Mutability {
Expand All @@ -332,11 +368,32 @@ impl Default for Mutability {
}
}

impl Mutability {
/// TODO
pub fn is_read(&self) -> bool {
match self {
Mutability::Read => true,
Mutability::ReadWrite => true,
Mutability::Write => false,
}
}

/// TODO
pub fn is_write(&self) -> bool {
match self {
Mutability::Read => false,
Mutability::ReadWrite => true,
Mutability::Write => true,
}
}
}

impl core::fmt::Display for Mutability {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Read => write!(f, "r"),
Self::ReadWrite => write!(f, "rw"),
Self::Write => write!(f, "w"),
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion cranelift/assembler-x64/meta/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn isle_macro(f: &mut Formatter, insts: &[dsl::Inst]) {
fmtln!(f, "() => {{");
f.indent(|f| {
for inst in insts {
inst.generate_isle_macro(f, "Gpr", "PairedGpr");
inst.generate_isle_macro(f, "Gpr", "PairedGpr", "Gpr");
}
});
fmtln!(f, "}};");
Expand All @@ -59,6 +59,7 @@ pub fn isle_definitions(f: &mut Formatter, insts: &[dsl::Inst]) {
f.line("(type AssemblerImm32 extern (enum))", None);
f.line("(type AssemblerSimm32 extern (enum))", None);
f.line("(type AssemblerReadGpr extern (enum))", None);
f.line("(type AssemblerWriteGpr extern (enum))", None);
f.line("(type AssemblerReadWriteGpr extern (enum))", None);
f.line("(type AssemblerReadGprMem extern (enum))", None);
f.line("(type AssemblerReadWriteGprMem extern (enum))", None);
Expand Down
9 changes: 5 additions & 4 deletions cranelift/assembler-x64/meta/src/generate/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl dsl::Format {
let ordered_ops: Vec<_> = self
.operands
.iter()
.filter(|o| o.disas)
.rev()
.map(|o| format!("{{{}}}", o.location))
.collect();
Expand Down Expand Up @@ -93,7 +94,7 @@ impl dsl::Format {
fmtln!(f, "let digit = 0;");
fmtln!(f, "rex.emit_two_op(buf, digit, {dst}.enc());");
}
[RegMem(dst), Imm(_)] => {
[RegMem(dst), Imm(_)] | [FixedReg(_), RegMem(dst)] | [FixedReg(_), FixedReg(_), RegMem(dst)] => {
let digit = rex
.digit
.expect("REX digit must be set for operands: [RegMem, Imm]");
Expand All @@ -105,7 +106,7 @@ impl dsl::Format {
});
fmtln!(f, "}}");
}
[Reg(dst), RegMem(src)] => {
[Reg(dst), RegMem(src)] | [Reg(dst), RegMem(src), Imm(_)] => {
fmtln!(f, "let {dst} = self.{dst}.enc();");
fmtln!(f, "match &self.{src} {{");
f.indent(|f| {
Expand Down Expand Up @@ -144,7 +145,7 @@ impl dsl::Format {
[FixedReg(_), Imm(_)] => {
// No need to emit a ModRM byte: we know the register used.
}
[RegMem(dst), Imm(_)] => {
[RegMem(dst), Imm(_)] | [FixedReg(_), RegMem(dst)] | [FixedReg(_), FixedReg(_), RegMem(dst)] => {
let digit = rex
.digit
.expect("REX digit must be set for operands: [RegMem, Imm]");
Expand All @@ -156,7 +157,7 @@ impl dsl::Format {
});
fmtln!(f, "}}");
}
[Reg(dst), RegMem(src)] => {
[Reg(dst), RegMem(src)] | [Reg(dst), RegMem(src), Imm(_)] => {
fmtln!(f, "let {dst} = self.{dst}.enc();");
fmtln!(f, "match &self.{src} {{");
f.indent(|f| {
Expand Down
93 changes: 66 additions & 27 deletions cranelift/assembler-x64/meta/src/generate/inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl dsl::Inst {
f.indent(|f| {
fmtln!(f, "fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {{");
f.indent(|f| {
for op in &self.format.operands {
for op in self.format.operands.iter().filter(|o| o.disas) {
let location = op.location;
let to_string = location.generate_to_string(op.extension);
fmtln!(f, "let {location} = {to_string};");
Expand Down Expand Up @@ -221,30 +221,59 @@ impl dsl::Inst {
/// # Panics
///
/// This function panics if the instruction has no operands.
pub fn generate_isle_macro(&self, f: &mut Formatter, read_ty: &str, read_write_ty: &str) {
pub fn generate_isle_macro(&self, f: &mut Formatter, read_ty: &str, read_write_ty: &str, write_ty: &str) {
use dsl::OperandKind::*;
let struct_name = self.name();
let operands = self
.format
.operands
.iter()
.map(|o| (o.location, o.generate_mut_ty(read_ty, read_write_ty)))
.collect::<Vec<_>>();
let ret_ty = match self.format.operands.first().unwrap().location.kind() {
Imm(_) => unreachable!(),
Reg(_) | FixedReg(_) => format!("cranelift_assembler_x64::Gpr<{read_write_ty}>"),
RegMem(_) => format!("cranelift_assembler_x64::GprMem<{read_write_ty}, {read_ty}>"),
};
let ret_val = match self.format.operands.first().unwrap().location.kind() {
Imm(_) => unreachable!(),
FixedReg(loc) | Reg(loc) | RegMem(loc) => format!("{loc}.clone()"),
};
let params = comma_join(
operands
.iter()
.map(|(l, ty)| format!("{l}: &cranelift_assembler_x64::{ty}")),
);
let args = comma_join(operands.iter().map(|(l, _)| format!("{l}.clone()")));
let mut params = Vec::new();
let mut args = Vec::new();
let mut rets = Vec::new();
for o in self.format.operands.iter() {
let kind = o.location.kind();
let arg = if o.mutability.is_read() {
let ty = o.generate_mut_ty(read_ty, read_write_ty, write_ty);
params.push(format!("{}: &cranelift_assembler_x64::{ty}", o.location));
format!("{}.clone()", o.location)
} else {
//..
};
args.push(arg);
}
// let operands = self
// .format
// .operands
// .iter()
// .filter(|r| r.mutability.is_read())
// .map(|o| (o.location, o.generate_mut_ty(read_ty, read_write_ty, write_ty)))
// .collect::<Vec<_>>();

// let rets = self
// .format
// .operands
// .iter()
// .filter(|r| r.mutability.is_write())
// .map(|o| o.location.kind())
// .collect::<Vec<_>>();
// let (ret_ty, ret_val) = match &rets[..] {
// [FixedReg(loc) | Reg(loc)] => {
// (format!("cranelift_assembler_x64::Gpr<{read_write_ty}>"), format!("{loc}.clone()"))
// }
// [RegMem(loc)] => (
// format!("cranelift_assembler_x64::GprMem<{read_write_ty}, {read_ty}>"),
// format!("{loc}.clone()"),
// ),
// [FixedReg(a) | Reg(a), FixedReg(b) | Reg(b)] => ("ValueRegs".to_string(), format!("xxx")),
// _ => panic!("don't know how to handle {rets:?} in ISLE"),
// };
// let ret_ty = match self.format.operands.first().unwrap().location.kind() {
// Imm(_) => unreachable!(),
// Reg(_) | FixedReg(_) => format!("cranelift_assembler_x64::Gpr<{read_write_ty}>"),
// };
// let ret_val = match self.format.operands.first().unwrap().location.kind() {
// Imm(_) => unreachable!(),
// FixedReg(loc) | Reg(loc) | RegMem(loc) => format!("{loc}.clone()"),
// };
let params = params.join(", ");
let args = args.join(", ");

// TODO: parameterize CraneliftRegisters?
fmtln!(f, "fn x64_{struct_name}(&mut self, {params}) -> {ret_ty} {{",);
Expand All @@ -271,6 +300,7 @@ impl dsl::Inst {
.format
.operands
.iter()
.filter(|r| r.mutability.is_read())
.map(|o| match o.location.kind() {
Imm(loc) => {
let bits = loc.bits();
Expand All @@ -285,10 +315,19 @@ impl dsl::Inst {
})
.collect::<Vec<_>>()
.join(" ");
let ret = match self.format.operands.first().unwrap().location.kind() {
Imm(_) => unreachable!(),
FixedReg(_) | Reg(_) => "AssemblerReadWriteGpr",
RegMem(_) => "AssemblerReadWriteGprMem",

let rets = self
.format
.operands
.iter()
.filter(|r| r.mutability.is_write())
.map(|o| o.location.kind())
.collect::<Vec<_>>();
let ret = match &rets[..] {
[FixedReg(_) | Reg(_)] => "AssemblerReadWriteGpr",
[RegMem(_)] => "AssemblerReadWriteGprMem",
[FixedReg(_) | Reg(_), FixedReg(_) | Reg(_)] => "ValueRegs",
_ => panic!("don't know how to handle {rets:?} in ISLE"),
};

f.line(format!("(decl {rule_name} ({params}) {ret})"), None);
Expand Down
Loading

0 comments on commit 8344547

Please sign in to comment.