Skip to main content

rucc_codegen/
lib.rs

1//! Instruction selection, scheduling, block layout, frames and prologue emission.
2//!
3//! Design: `spec/10-backend.md`. Layer rank 11, see `spec/18-package-layout.md`.
4//!
5//! # Status
6//!
7//! The lowering tables are here. `rules/x86-64.rules` is compiled into a matching automaton when
8//! this crate is built, and [`select`] is the walk over it: hand it a term and it gives back the
9//! rule that fires and what the pattern bound. No lowering is written as `match` arms in this
10//! crate and none ever will be, which is the settled decision `spec/10-backend.md` section 10.2
11//! records.
12//!
13//! The selector is here too. [`lower`] walks a function and builds machine IR out of what the
14//! table gives back, and [`term`] is how an IR instruction is shown to the matcher. Between them
15//! they cover the arithmetic the rule file covers, which is every integer operation at every
16//! width the machine has one for. Nothing with an effect is covered, because no rule for one is
17//! written yet.
18//!
19//! [`frame`] is what a function's stack looks like while it runs: which registers the prologue has
20//! to put back, where every spilled value went, and how many bytes the stack pointer moves. It is
21//! worked out after allocation because the largest area in most frames is the spill slots and
22//! nothing knows how many of those there are until the allocator has finished running out of
23//! registers.
24//!
25//! What is not here yet is the prologues and the block layout. Both land in M3.
26//!
27//! Every crate in the workspace is published, and publishing implies a promise. This one is
28//! tier 3: its Rust API is explicitly unstable and will change without a major version bump.
29//! Depend on the `rucc` binary's behaviour, not on this.
30
31#![doc(html_root_url = "https://docs.rs/rucc-codegen/0.3.4")]
32
33pub mod frame;
34pub mod lower;
35pub mod select;
36pub mod term;
37
38/// The milestone in `spec/17-milestones.md` that fills this crate in.
39pub const MILESTONE: &str = "M3";
40
41#[cfg(test)]
42mod tests {
43    #[test]
44    fn milestone_is_recorded() {
45        assert!(super::MILESTONE.starts_with('M'));
46    }
47}