1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! How much of a register each instruction reads and writes.
//!
//! Design: `spec/optimizer/37-machine-level-optimization.md` section 37.4.
//!
//! A register is one register at every width, and what says how much of it an instruction is
//! about is the instruction. `movzbl %sil, %esi` writes thirty two bits and reads eight of them,
//! `movb %sil, %r12b` writes eight and reads eight, and put the two next to each other and the
//! twenty four bits the first one worked out are bits nothing reads. Finding that out is the bit
//! group liveness of `gcc/ext-dce.cc`, which tracks what is live per group of bits rather than
//! per register, and what it needs from a target is this: for each operand of each instruction,
//! how much of it the instruction names.
//!
//! It is here rather than in the pass for the reason [`crate::FrameInsts`] and
//! [`crate::BranchInsts`] are here. The pass is in a pipeline crate and
//! `spec/10-backend.md` section 10.8 says a pipeline crate holds no target-specific code, so what
//! the pass knows about a machine arrives as a description rather than as a name it says out
//! loud.
//!
//! # Why two questions rather than a table of instructions
//!
//! Neither question is about a particular instruction. The first is how wide an operand is, which
//! every instruction of every target has an answer to, and the second is whether an instruction
//! is one that copies the low bits of its source into its destination, which is the one family
//! the transformation acts on. A target with no widening instructions answers `false` to the
//! second everywhere and the pass finds nothing, which is the right answer rather than a special
//! case.
/// What a pass has to know about a machine to work out which bits of a register anything reads.
///
/// Both are functions of an opcode's name rather than tables, because a target already has the
/// table both of them read: the assembly listing names each operand at the width the instruction
/// uses it at, and the encoder is generated from the same description, so the widths here are the
/// ones the machine really has rather than a second opinion about them.