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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! What a machine level pass has to ask before it may keep a rewrite.
//!
//! Design: `spec/optimizer/37-machine-level-optimization.md` sections 37.2 and 37.3.
//!
//! A machine level rewrite is speculative. Section 37.3 quotes `gcc/combine.cc` on the shape of
//! it: substitute the earlier instruction into the later one, ask the machine description whether
//! what came out is an instruction this target has, install it if it is and put everything back if
//! it is not. GCC's word for the asking is `recog`, the machine description is the `.md` file, and
//! the reason the arrangement is worth copying is in the same section: a target that adds a
//! pattern makes the optimizer smarter without anybody editing the optimizer.
//!
//! This is that question for this compiler. A pass proposes an instruction and asks whether the
//! target has one of that shape, and a target answers out of the description it already keeps for
//! the allocator and the encoder rather than out of a second list written for this. Two lists
//! would be two opinions about one machine and they would disagree eventually.
//!
//! # What it does not answer
//!
//! Whether the rewrite is worth making. That is the pass's own question and no target has an
//! opinion about it.
//!
//! Whether the values are right. An instruction of a shape this target has can still read the
//! wrong register, and what checks that is `rucc_regalloc::check` after allocation and the shape
//! of the pass before it. This says the instruction exists and nothing further.
use crateOperandDesc;
/// What a pass has to know about a machine to tell an instruction it has from one it does not.
///
/// Every question is of a name, for the reason [`crate::BitInsts`] takes names: the pass is in a
/// pipeline crate, `spec/10-backend.md` section 10.8 says a pipeline crate holds no target
/// specific code, so an opcode is a name to it and what any name means is the target's answer.