Skip to main content

rucc_target/x86_64/
insts.rs

1//! What each x86-64 machine instruction does with its operands.
2//!
3//! Design: `spec/10-backend.md` sections 10.1 and 10.2.
4//!
5//! The lowering rules say which machine instruction computes an IR term and `rucc-verify`
6//! proves that it does. Neither says where the operands may live, and that is the other half of
7//! what the backend needs: a two-address instruction destroys its first source, a shift by a
8//! variable count wants the count in `cl`, and a division has its dividend and its quotient in
9//! registers the program did not choose. The allocator has to be told all of it, and the rule
10//! set is the wrong place to write it, because it is a fact about the instruction rather than
11//! about the rewrite, and the same instruction is reached by many rules.
12//!
13//! So each opcode has a [`Form`] here, and a form is the operand vector of every instruction with
14//! it. The name is the one the rule set writes without the `x64.` in front, because a machine
15//! opcode in the machine IR is a name and this is where the name is given a meaning that is not
16//! the encoder's.
17//!
18//! Every opcode, and not only the ones a rule selects. A prologue pushes and a spill stores, and
19//! neither is anything a pattern could match, so [`crate::FrameInsts`] names them and the block
20//! layout's jumps are named by [`crate::BranchInsts`]. All of them end up in the same function and
21//! everything downstream reads them the same way, so a second table for the ones a rule cannot
22//! reach would be a second place for an opcode to be missing from.
23//!
24//! # What a form is not
25//!
26//! It is not a promise that the opcode is one instruction. `imul_rr_8` is the form of a
27//! two-address multiply and there is no two-operand `imul` on eight bit registers, so the
28//! encoder writes more than one instruction for it, and the same is true of every division and
29//! of the compare and set pairs. What a form promises is what the allocator has to know, which
30//! is what each operand is read or written as and where it is allowed to be, and that is the
31//! same whether the opcode becomes one instruction or four.
32//!
33//! Nothing here mentions flags. A comparison and the set that reads it are one opcode, and a
34//! shift reads the flags of nothing, so no instruction in this description has a flag operand
35//! and the allocator never sees one. That is a deliberate constraint on the rule set rather
36//! than a simplification of the machine.
37
38use crate::operand::{Constraint, OperandDesc};
39use crate::x86_64::{GPR, RAX, RCX, RDX, XMM, xmm};
40
41use Form::{
42    AluRi, AluRr, AluVec, ArgVal, ArgValVec, ArithX87, Barrier, BrCond, Call, Cmp, CmpRi, CmpSet,
43    CmpSetRi, CmpSetVec, CmpSetVecBoth, CmpSetX87, CmpSetX87Both, CmpXchg, Convert, ConvertFromVec,
44    ConvertToVec, ConvertVec, CtrlX87, DivQuo, DivRem, Jcc, Jmp, Landing, Lea, Load, LoadImm,
45    LoadVec, Move, MoveVec, Nop, Pop, PopX87, Probe, Push, PushX87, Ret, RetVal, RetVal2,
46    RetVal2Vec, RetValVec, Rmw, ShiftCl, ShiftRi, Store, StoreVec, Test, TestCmov, UnaryR,
47    UnaryX87,
48};
49
50/// The operand vector one machine instruction has.
51///
52/// A form rather than a list per opcode, because a hundred and fifty six opcodes have eleven
53/// answers between them and writing the eleven once is what makes a mistake in one of them a
54/// mistake a test can find.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum Form {
57    /// A destination and an immediate, which is `mov r, imm`.
58    LoadImm,
59    /// Two-address arithmetic on two registers: the destination is the first source, which the
60    /// allocator is the one that has to arrange.
61    AluRr,
62    /// Two-address arithmetic on a register and an immediate.
63    AluRi,
64    /// Two-address arithmetic on one register, which is negation and complement.
65    UnaryR,
66    /// A two-address shift by a constant.
67    ShiftRi,
68    /// A two-address shift by a count, which this machine reads from `cl` and nowhere else.
69    ShiftCl,
70    /// A comparison and the byte it sets, which writes a destination unrelated to either
71    /// source rather than destroying one of them.
72    CmpSet,
73    /// The same against a constant, which the machine compares against without being handed a
74    /// register holding it.
75    ///
76    /// One register read rather than two, and the constant on the instruction. It is not
77    /// two-address the way [`Form::AluRi`] is, for the reason [`Form::CmpSet`] is not either:
78    /// what a comparison writes is the flags, and the byte the set behind it writes is a
79    /// destination neither source has any claim on.
80    CmpSetRi,
81    /// A comparison that keeps nothing but the flags.
82    ///
83    /// The same instruction as the first half of [`Form::CmpSet`] with the second half gone. It
84    /// exists because a branch on the answer of a comparison does not need the answer in a
85    /// register: the jump reads the flags the comparison set. Nothing selects one of these, since
86    /// what it computes is not a value and a rule replaces a term with a term. The block layout
87    /// writes one, in place of a comparison and a test it found next to each other, and writes the
88    /// jump that reads its flags immediately after it.
89    Cmp,
90    /// The same against a constant, which is [`Form::CmpSetRi`] with the byte gone.
91    CmpRi,
92    /// A move between widths, which reads one register and writes another.
93    Convert,
94    /// The quotient of a division, which comes back in `rax` and destroys `rdx` on the way.
95    DivQuo,
96    /// The remainder of a division, which comes back in `rdx` and destroys `rax` on the way.
97    DivRem,
98    /// An address computation, whose registers are in an addressing mode rather than in the
99    /// operand vector, and which the builder puts there.
100    Lea,
101    /// A load: a destination register, and an addressing mode the value comes from.
102    Load,
103    /// A store: an addressing mode the value goes to, and the register it comes out of. It
104    /// writes no register at all, which makes it the first form here with no definition in it.
105    Store,
106    /// A touch of the page an address is on, which reads it and writes back what was already
107    /// there.
108    ///
109    /// An addressing mode and an immediate and no register at all, which no other form here is.
110    /// The immediate is the zero that makes the instruction leave the byte alone, and it is
111    /// written rather than assumed because it is what the machine reads. The address is where the
112    /// stack pointer now is, so the registers in the vector are the ones the addressing mode
113    /// brought and the description has none of its own.
114    ///
115    /// Nothing selects one. The only thing that writes one is a prologue taking a frame under
116    /// `-fstack-clash-protection`, which is `rucc_codegen::finish`, and it is described here
117    /// because the allocator and the encoder read this table about every instruction in a
118    /// function whoever wrote it.
119    Probe,
120    /// The value a function gives back, in the register it is given back in.
121    ///
122    /// It is not the `ret` instruction and it encodes to nothing. What the selector can do about
123    /// a return is put the value where the caller will look for it, and what it cannot do is
124    /// leave, because the epilogue has to give the frame back first and the epilogue is written
125    /// long after selection has finished. So this is the whole of the return that a lowering rule
126    /// gets to decide, and `rucc_codegen::finish` appends the rest to the same block.
127    ///
128    /// The point of it surviving as an instruction rather than being nothing at all is the
129    /// operand: a read constrained to the return register is how the allocator is told to get
130    /// the value there, and it is what keeps the value alive that far.
131    RetVal,
132    /// The second register a value comes back in, when it takes two of them.
133    ///
134    /// [`Form::RetVal`] one place further along the convention's list of return registers. A
135    /// structure of at most sixteen bytes comes back in up to two registers, and which register
136    /// each half goes in is the classification's answer, so a return of two values is built from
137    /// the convention the way a call is rather than matched by a rule. There is no third of these
138    /// because no convention this target has returns in three registers.
139    RetVal2,
140    /// A value the caller already passed, in the register it arrived in.
141    ///
142    /// The mirror of [`Form::RetVal`] and the same kind of thing: it encodes to nothing, and what
143    /// it is for is telling the allocator where a value already is. A function's arguments are
144    /// there before its first instruction runs, so something has to define them, and a block
145    /// parameter cannot, because there is no edge into the entry block for a move to go on.
146    ///
147    /// Which register is not written here, unlike the return, because the answer depends on the
148    /// argument's position and on every argument before it. `rucc_codegen::abi` works that out
149    /// from the convention and puts it on the operand.
150    ArgVal,
151    /// The condition a block leaves on, in a register.
152    ///
153    /// The third form here that encodes to nothing, and the smallest. Where the two arms go is on
154    /// the block rather than on the instruction, so this says nothing about either of them: it
155    /// reads the condition, which keeps the value alive to the end of the block and gets it into
156    /// a register. What turns it into a test and a jump is the block layout, which is the only
157    /// thing that knows which of the two arms falls through and therefore which way round the
158    /// jump goes. What takes the test back out again, where the condition came from a comparison
159    /// that already set the flags, is the peephole `spec/10-backend.md` section 10.9 describes.
160    /// It is not a rule and cannot be one, for the reason [`Form::CmpSet`] is one form rather than
161    /// two: what the comparison leaves for the jump is the flags, and the flags are not a value a
162    /// pattern could bind or a solver could be asked about.
163    ///
164    /// An unconditional jump is not a form at all, because there is nothing left of one once the
165    /// edge is on the block.
166    BrCond,
167    /// A comparison of a register against itself, which is what asks whether it is zero.
168    ///
169    /// The first instruction here that sets the flags and says nothing about them, which is the
170    /// same arrangement every instruction here has: the flags are not an operand and the
171    /// allocator never sees one. What makes that sound is that this and the jump that reads it
172    /// are put in by the block layout, next to each other, after allocation has finished, so
173    /// there is nothing left that could put an instruction between them.
174    /// A test of a condition and the conditional move that reads its flags, as one instruction.
175    ///
176    /// The same argument [`Form::CmpSet`] is written under. The flags between the two halves are
177    /// not a value a solver can be asked about, so the unit a rule names is the pair that produces
178    /// the answer, and nothing may be put between them because there is no one instruction here to
179    /// put it between.
180    ///
181    /// Three registers read and one written, and the written one is the value chosen when the
182    /// condition is false, because that is what a conditional move is: the destination already
183    /// holds one answer and the instruction overwrites it with the other. So the destination reuses
184    /// the operand holding the false arm, which is the same two-address constraint the arithmetic
185    /// has and is handled the same way, by a copy the allocator inserts when the false arm is still
186    /// live afterwards.
187    TestCmov,
188    Test,
189    /// A jump taken when the flags say so, whose target is on the block.
190    ///
191    /// Where it goes is the block's first successor, for the reason every other arm is on the
192    /// block: an instruction is twenty four bytes and a block reference would not fit in one, and
193    /// the successors of a block are the thing every pass over the CFG already reads. The second
194    /// successor is where the block goes when the jump is not taken, and after the layout has run
195    /// that is always the block laid out next, which is why nothing is written for it.
196    Jcc,
197    /// A jump always taken, whose target is on the block.
198    ///
199    /// The one this becomes when the block it goes to is not the next block in the layout. A
200    /// block that falls into the next one has no jump at all, which is what laying blocks out in
201    /// a good order is worth.
202    Jmp,
203    /// A call, whose operand vector is not a fact about the instruction.
204    ///
205    /// Empty for a different reason than the jumps are. A jump has no operands because there is
206    /// nothing for it to read, and this has none because there is nothing true of
207    /// every call: how many values it passes, which registers they are in, whether anything comes
208    /// back and where, are all facts about the signature and the convention. So the operands of a
209    /// call are built where it is built, by `rucc_codegen::abi`, the same way an argument's
210    /// register is.
211    ///
212    /// What is the same about every call is the rest of it, and none of that is an operand
213    /// either. The registers the convention does not preserve are gone across it, which is said
214    /// with a definition per register that nothing reads, and that is what stops the allocator
215    /// from leaving a value in one. The bytes below the stack pointer the arguments that did not
216    /// fit in registers occupy are the frame's, which is why the selector reports how many a
217    /// function's widest call needs rather than writing anything about them here.
218    ///
219    /// A call through an address is the same form. The address is an operand and is a fact about
220    /// the instruction rather than about the signature, so it is the one operand of a call that
221    /// could have been written here, and it is not: an index into the operand vector is what a
222    /// row of this table names an operand by, and how many registers a call writes before it
223    /// reads anything is a different number for every call. What names it instead is
224    /// [`Arg::Through`](crate::x86_64::Arg::Through), which is the first operand read rather than
225    /// the operand at a place.
226    Call,
227    /// A copy from one general purpose register to another.
228    ///
229    /// The first form here no rule reaches. A copy is what the allocator writes when the two ends
230    /// of a value could not be given the same register, and what a prologue writes when it puts
231    /// the stack pointer in the frame pointer, and neither of those is a term a pattern could
232    /// match. It is a whole register at a time whatever the value in it is worth, because a copy
233    /// of half a register is a copy that has to know what the other half was for.
234    Move,
235    /// A register put on the stack, which is how a prologue saves one the convention preserves.
236    Push,
237    /// A register taken off it, which is how the epilogue gives it back.
238    Pop,
239    /// Leaving, which is the instruction a lowering rule cannot select for the reason
240    /// [`Form::RetVal`] gives: the frame has to be given back first and the frame is worked out
241    /// long after selection has finished.
242    Ret,
243    /// A barrier, which reads nothing, writes nothing and is only its effect on the order other
244    /// instructions become visible in.
245    ///
246    /// The same empty operand list as [`Form::Ret`] and a separate form because a form is read as
247    /// what an instruction is as well as what its operands are, and an epilogue and a fence have
248    /// nothing to do with each other. Neither is reachable from a rule, and for the same shape of
249    /// reason: there is nothing about either that a proof over bitvectors could discharge, since
250    /// what makes them right is the frame in one case and the memory model in the other.
251    Barrier,
252    /// A landing pad, which reads nothing, writes nothing and says that the address it is at is
253    /// one an indirect call or jump is allowed to arrive at.
254    ///
255    /// What `-fcf-protection=branch` asks for. On a machine that checks, an indirect transfer to
256    /// an address that is not one of these faults, so the set of addresses a corrupted function
257    /// pointer can reach is the set of places somebody meant to be reachable that way rather than
258    /// every byte of the program.
259    ///
260    /// The same empty operand list as [`Form::Barrier`] and a form of its own for the same reason:
261    /// a fence and a landing pad are not the same kind of thing, and a form is read as what an
262    /// instruction is as much as what its operands are. Nothing selects one. The only thing that
263    /// writes one is a prologue, which is `rucc_codegen::finish`.
264    Landing,
265    /// A byte that does nothing, written so that something else can be written over it later.
266    ///
267    /// What `-fpatchable-function-entry=` asks for. The bytes are reserved rather than used: a
268    /// tracer or a live patcher replaces them with a jump or a call once the program is running,
269    /// and what it needs from the compiler is room at a known address and a promise that nothing
270    /// jumps into the middle of it.
271    ///
272    /// The same empty operand list as [`Form::Landing`] and a form of its own for the same reason.
273    /// A pad that means something to the hardware and a byte that means nothing to anybody are not
274    /// the same kind of instruction, and nothing selects either: the only thing that writes one is
275    /// a prologue, which is `rucc_codegen::finish`.
276    Nop,
277    /// A compare and exchange, which is the one instruction here that names four registers and
278    /// only two of them by choice.
279    ///
280    /// What the machine does is compare what is at an address against `rax`, write the second
281    /// source there when the two were equal, and leave what it found in `rax` either way. So `rax`
282    /// is read and written and is not something the allocator picks, which is the same shape a
283    /// division has and is written here the same way.
284    ///
285    /// The second definition is the byte saying whether the exchange went through, which the `setz`
286    /// behind the instruction writes. It is a definition rather than a fixed register so that the
287    /// allocator places it, and it is a definition at all so that the allocator knows a value lands
288    /// there: two definitions of one instruction are live at the same point, so the register this
289    /// gets is never `rax`, which is what keeps the `setz` from writing over the value.
290    CmpXchg,
291    /// A read modify write of a whole object at an address, which is one instruction on this
292    /// machine for the exchange and for the add and is a loop for everything else.
293    ///
294    /// The same two operands as any other two-address arithmetic, and a separate form because the
295    /// second place it works on is memory rather than a register: an addressing mode is on the
296    /// instruction, which is the difference [`Form::takes_mem`] reads. The value it answers is the
297    /// one that was there before, and it lands in the register the operand arrived in, which is what
298    /// makes it two-address in the first place and is why the destination reuses the source.
299    ///
300    /// The `lock` in front is not part of this. An exchange with memory is indivisible on this
301    /// machine whether the prefix is written or not, and an add is not, so the prefix belongs to the
302    /// spelling of each instruction rather than to the shape they share.
303    Rmw,
304    /// A copy from one vector register to another.
305    ///
306    /// The same thing as [`Form::Move`] and a separate form rather than the same one, because a
307    /// form is the class each of its operands is drawn from and these two are drawn from
308    /// different classes. That is also why there are three of these rather than one: a spill and
309    /// a reload of a vector register are a different instruction from a spill and a reload of a
310    /// general purpose one, and the allocator picks between them by asking the register file
311    /// which class the value is in.
312    MoveVec,
313    /// A vector register read back from the stack.
314    LoadVec,
315    /// A vector register written to it.
316    StoreVec,
317    /// Two-address arithmetic on two vector registers, which is every scalar floating point
318    /// operation this machine has.
319    ///
320    /// [`Form::AluRr`] in the other class and a separate form for the same reason the three moves
321    /// above are separate: a form is which class each of its operands comes from, and an allocator
322    /// handed the wrong one would put a float in a register that cannot hold one. The destination
323    /// reuses the first source here too, because `addsd` writes its answer over one of the two it
324    /// was given, exactly as `addq` does.
325    AluVec,
326    /// The value a function gives back, when it goes back in a vector register.
327    ///
328    /// [`Form::RetVal`] in the other class. It encodes to nothing for the same reason and exists
329    /// for the same reason: a read constrained to the register the convention returns in is how
330    /// the allocator is told where the value has to end up.
331    RetValVec,
332    /// [`Form::RetVal2`] in the other file.
333    RetVal2Vec,
334    /// A value the caller already passed, when it arrived in a vector register.
335    ///
336    /// [`Form::ArgVal`] in the other class, unconstrained here and constrained where it is built,
337    /// for the reason that one gives.
338    ArgValVec,
339    /// A conversion from one float format to the other, which reads a vector register and writes
340    /// one.
341    ///
342    /// [`Form::Convert`] in the other class, and the reason there are three of these is the reason
343    /// there are two of that: a form is which file each of its operands is drawn from, and a
344    /// conversion is the one kind of instruction here whose answer is not the same for both of
345    /// them. What the destination is not is a reuse of the source, which every other vector
346    /// instruction here is: `cvtss2sd` writes a register it did not read.
347    ConvertVec,
348    /// A conversion that reads a general purpose register and writes a vector one, which is an
349    /// integer becoming a float.
350    ConvertToVec,
351    /// A conversion that reads a vector register and writes a general purpose one, which is a
352    /// float becoming an integer.
353    ConvertFromVec,
354    /// A comparison of two floats and the byte it sets, which reads two vector registers and
355    /// writes a general purpose one.
356    ///
357    /// [`Form::CmpSet`] with the two sources in the other file. The destination is in this one
358    /// because a truth value is a byte and a byte is not a thing the vector registers hold: what
359    /// `ucomisd` writes is the flags, and reading the flags is `setcc` and nothing else.
360    CmpSetVec,
361    /// The same, when the condition takes two of those bytes and a boolean operation to spell.
362    ///
363    /// Two of the sixteen float comparisons are not one condition on this machine. `ucomisd` says
364    /// less, greater, equal or unordered in three flag bits, and every predicate but two is one of
365    /// those bits: equal on its own is the flag that means equal or unordered, so an ordered
366    /// equality is that flag and the one that says the operands were ordered, put together with an
367    /// `and`. Its negation is the other one, with an `or`.
368    ///
369    /// So the instruction writes a second byte it then reads back, and that byte is written here
370    /// as a second definition, the way `idiv` writes down the register it destroys on the way. It
371    /// is a register the allocator picks and nothing else can be in it, because a definition that
372    /// is live where the first one is live is a definition that cannot share with it.
373    CmpSetVecBoth,
374    /// Memory pushed onto the x87 stack, which is `fldt` and the four conversions that come up.
375    ///
376    /// The width and the format are in the opcode rather than in the form, because they are what
377    /// the instruction does and not what the allocator has to arrange. `fldt` reads the format the
378    /// stack already holds, `flds` and `fldl` read a narrower float and convert on the way in, and
379    /// `fildl` and `fildll` read an integer. All five leave one value on the stack and none of them
380    /// can be got wrong by an allocator, so all five are this.
381    ///
382    /// The first form here with no register operand of its own. It writes no register because the
383    /// place the value lands is the top of the x87 stack, and `ClassInfo::allocatable` says why
384    /// that is not a register anything may be allocated to: `st0` is wherever the top happens to
385    /// be, so a name for it does not fix a register the way `rax` does. It reads no register
386    /// either, for the same reason in the other direction. The registers it really touches are
387    /// the ones in the addressing mode, and the builder puts those in the vector the way it does
388    /// for every other instruction that carries an address.
389    ///
390    /// So the allocator sees an instruction that reads an address and does something, which is
391    /// what a store looks like to it, and that is the whole of what it has to know.
392    PushX87,
393    /// The top of the x87 stack popped into memory, which is `fstpt` and the four that go down.
394    ///
395    /// The other half of [`Form::PushX87`] and the same operand list. Every use of the x87 stack
396    /// this target makes is one of these behind one or more of those, which is the discipline
397    /// `spec/10-backend.md` section 10.8 writes down: the stack is empty before the first push of
398    /// a group and empty again after the last pop, so no two groups can be interleaved and nothing
399    /// depends on how deep the stack was when a group started.
400    ///
401    /// Every one of them pops, which is why there is no form here for the ones that do not.
402    /// `fst` without the `p` exists and nothing selects it, since a value that stays on the stack
403    /// after it has been written out is a value the next group would have to know about.
404    PopX87,
405    /// The x87 control word read out of the unit or written back into it.
406    ///
407    /// `fnstcw` and `fldcw`, which are the only two instructions here that touch the x87 and are
408    /// neither a push nor a pop. The operand list is the same as the two above and the reason for
409    /// a form of their own is the same reason a barrier is not a return: a form says what an
410    /// instruction is as well as what its operands are, and the depth of the stack is the thing
411    /// the other two forms are read for.
412    ///
413    /// What they are for is the one C conversion this machine has no single instruction for. C
414    /// cuts a float towards zero and the x87 rounds the way its control word says, which is to
415    /// nearest, so an eighty bit float becoming an integer is the control word saved, changed,
416    /// used and put back. `spec/10-backend.md` section 10.8 writes the group out and says why it
417    /// is that rather than `fisttp`.
418    CtrlX87,
419    /// Arithmetic on the two values at the top of the x87 stack, which leaves one.
420    ///
421    /// The same empty operand list the three above have and the same reason for it, one step
422    /// further on: both sources and the destination are depths on a stack nothing allocates from,
423    /// so there is nothing here for the allocator to arrange at all. This is the first form in
424    /// this table with no operands and no address either, which makes it the first instruction the
425    /// allocator sees that touches nothing it knows about.
426    ///
427    /// Which of the two values is on top is the code generator's business and is the whole of what
428    /// a subtraction and a division have two of these for. A pair of registers can be named in
429    /// either order and a pair of depths cannot, so `fsubp` and `fsubrp` are two instructions
430    /// rather than one instruction written twice.
431    ArithX87,
432    /// Arithmetic on the top of the x87 stack alone, which leaves it where it was.
433    ///
434    /// A sign flipped and a sign cleared, which are the two things this machine does to an eighty
435    /// bit float without reading it as a number. Neither raises on anything, neither rounds, and
436    /// neither can be got wrong by an allocator, so both are this.
437    ///
438    /// Separate from [`Form::ArithX87`] because it does not pop. The depth of the stack after one
439    /// of these is the depth before it, and the depth is what these forms are read for.
440    UnaryX87,
441    /// A comparison of the two values at the top of the x87 stack and the byte it sets.
442    ///
443    /// [`Form::CmpSetVec`] on the other unit, and the same argument: what the comparison writes is
444    /// the flags, reading the flags is `setcc` and nothing else, and the two are one opcode here
445    /// because nothing in between them is a value a rule could name. The destination is a general
446    /// purpose register because a truth value is a byte.
447    ///
448    /// Three instructions rather than two, and the third is the one worth writing down. The
449    /// comparison takes one value off the stack and there were two on it, so a pop that throws its
450    /// value away is part of this opcode. Leaving it to whatever came next would be leaving the
451    /// stack deeper than the group found it, and `spec/10-backend.md` section 10.8 is a rule about
452    /// a group rather than about a block.
453    CmpSetX87,
454    /// The same, when the condition takes two of those bytes and a boolean operation to spell.
455    ///
456    /// [`Form::CmpSetVecBoth`] word for word, because the flags an x87 comparison writes are the
457    /// flags a vector comparison writes: less, greater, equal or unordered in three bits, with
458    /// every predicate but two being one of them. The second byte is a second definition for the
459    /// same reason it is there.
460    CmpSetX87Both,
461}
462
463// The destination of a two-address instruction is the operand after it, which is the first
464// source. Writing it as a reuse rather than as a copy is what lets the allocator put the two in
465// one register when the source dies here and insert the copy when it does not.
466static TWO_ADDRESS_RR: [OperandDesc; 3] = [
467    OperandDesc::write(GPR).with(Constraint::Reuse(1)),
468    OperandDesc::read(GPR),
469    OperandDesc::read(GPR),
470];
471static TWO_ADDRESS_RI: [OperandDesc; 2] =
472    [OperandDesc::write(GPR).with(Constraint::Reuse(1)), OperandDesc::read(GPR)];
473// The count is in `cl` because that is the only register this machine shifts by. It is the
474// whole of `rcx` as far as the allocator is concerned, since `cl` is part of `rcx` and nothing
475// else may be using the rest of it.
476static SHIFT_CL: [OperandDesc; 3] = [
477    OperandDesc::write(GPR).with(Constraint::Reuse(1)),
478    OperandDesc::read(GPR),
479    OperandDesc::read(GPR).with(Constraint::Fixed(RCX)),
480];
481static LOAD_IMM: [OperandDesc; 1] = [OperandDesc::write(GPR)];
482static ONE_TO_ONE: [OperandDesc; 2] = [OperandDesc::write(GPR), OperandDesc::read(GPR)];
483static TWO_TO_ONE: [OperandDesc; 3] =
484    [OperandDesc::write(GPR), OperandDesc::read(GPR), OperandDesc::read(GPR)];
485// The dividend is in `rax` and the divisor is anywhere else. A division produces both answers
486// and this opcode is one of them, so the register the other one lands in is written here as
487// well, and it is written early: the sign extension that fills it runs before the division
488// reads its divisor, so the divisor may not be sitting in it, and an early definition is how a
489// target says exactly that.
490static DIV_QUO: [OperandDesc; 4] = [
491    OperandDesc::write(GPR).with(Constraint::Fixed(RAX)),
492    OperandDesc::write_early(GPR).with(Constraint::Fixed(RDX)),
493    OperandDesc::read(GPR).with(Constraint::Fixed(RAX)),
494    OperandDesc::read(GPR),
495];
496static DIV_REM: [OperandDesc; 4] = [
497    OperandDesc::write(GPR).with(Constraint::Fixed(RDX)),
498    OperandDesc::write_early(GPR).with(Constraint::Fixed(RAX)),
499    OperandDesc::read(GPR).with(Constraint::Fixed(RAX)),
500    OperandDesc::read(GPR),
501];
502// A compare and exchange, whose first two entries are the two values it produces and whose last
503// two are the value it compares against and the value it puts there. `rax` is fixed at both ends
504// because the machine reads the expected value out of it and leaves what it found in it, and the
505// address is not here for the reason no address is: the builder appends the registers of the
506// addressing mode behind everything written down.
507static CMPXCHG: [OperandDesc; 4] = [
508    OperandDesc::write(GPR).with(Constraint::Fixed(RAX)),
509    OperandDesc::write(GPR),
510    OperandDesc::read(GPR).with(Constraint::Fixed(RAX)),
511    OperandDesc::read(GPR),
512];
513// A read modify write, whose two entries are the value that was there before and the value the
514// operation is done with. They are one register: the instruction leaves the old value in the
515// register it read the operand out of, which is the same two-address shape the arithmetic above has
516// and is said the same way. The address is not here for the reason no address is.
517static READ_MODIFY_WRITE: [OperandDesc; 2] =
518    [OperandDesc::write(GPR).with(Constraint::Reuse(1)), OperandDesc::read(GPR)];
519static ADDRESS: [OperandDesc; 1] = [OperandDesc::write(GPR)];
520// A load writes one register and reads none, because the registers it reads are the ones in
521// the addressing mode and the builder is what puts those in the vector.
522static LOAD: [OperandDesc; 1] = [OperandDesc::write(GPR)];
523// A store writes nothing. It is the first instruction here that produces no value, which is
524// what having an effect means, and the allocator needs no more than that: an instruction with
525// no definition keeps nothing alive past it.
526static STORE: [OperandDesc; 1] = [OperandDesc::read(GPR)];
527// An integer comes back in `rax` on every convention this machine has, which is why the register
528// is written here rather than read out of the convention the session was given. A test checks it
529// against `SYSV` and `WIN64` rather than leaving it as something a reader has to take on trust,
530// and a convention that ever disagrees is one that will fail that test rather than compile.
531static RET_VAL: [OperandDesc; 1] = [OperandDesc::read(GPR).with(Constraint::Fixed(RAX))];
532// The second half of a structure that comes back in two registers, which is `rdx` on the one
533// convention that has a second register to come back in. Written here for the reason above and
534// held against the convention by the same test.
535static RET_VAL_2: [OperandDesc; 1] = [OperandDesc::read(GPR).with(Constraint::Fixed(RDX))];
536// An argument is unconstrained here and constrained where it is built, because which register the
537// third argument is in is a fact about the convention and about the two arguments before it, and
538// none of that is available to a table of shapes. The class is the same reason: an argument in a
539// vector register is one of these too, with the class the convention names for it.
540static ARG_VAL: [OperandDesc; 1] = [OperandDesc::write(GPR)];
541// A condition is in any register at all, since the instruction this becomes is a `test` of a
542// register against itself and every general purpose register can be tested.
543static BR_COND: [OperandDesc; 1] = [OperandDesc::read(GPR)];
544// A call names no operand here at all, because none of them is a fact about the instruction. What
545// it passes and what comes back are facts about the signature it is made against.
546static CALL: [OperandDesc; 0] = [];
547// A test of a register against itself reads the same register twice. It is written once here,
548// because the two operands of the instruction are the same register and the allocator would
549// otherwise be free to put two different ones there.
550// The condition, the arm taken when it holds and the arm taken when it does not. The destination
551// is the false arm, since a conditional move overwrites what is already in the register, which is
552// the same shape the two-address arithmetic above has and gets the same `Reuse`.
553static TEST_CMOV: [OperandDesc; 4] = [
554    OperandDesc::write(GPR).with(Constraint::Reuse(1)),
555    OperandDesc::read(GPR),
556    OperandDesc::read(GPR),
557    OperandDesc::read(GPR),
558];
559static TEST: [OperandDesc; 1] = [OperandDesc::read(GPR)];
560// A comparison that keeps only the flags, which is `TWO_TO_ONE` and `ONE_TO_ONE` with the byte
561// they wrote gone. Both sources stay reads and neither is tied to anything, since there is no
562// destination left for either of them to be destroyed by.
563static CMP: [OperandDesc; 2] = [OperandDesc::read(GPR), OperandDesc::read(GPR)];
564static CMP_RI: [OperandDesc; 1] = [OperandDesc::read(GPR)];
565// A jump reads nothing and writes nothing. Where it goes is on the block, not in an operand.
566static JUMP: [OperandDesc; 0] = [];
567// A push reads a whole register and a pop writes one. Neither says anything about the stack
568// pointer, which every one of them moves: it is not an operand because nothing may be allocated
569// to it, and a frame that has one of these in it is a frame that has already accounted for the
570// eight bytes it costs.
571static PUSH: [OperandDesc; 1] = [OperandDesc::read(GPR)];
572static POP: [OperandDesc; 1] = [OperandDesc::write(GPR)];
573// Leaving reads the return address and writes the instruction pointer, and neither of those is a
574// register anything here can name, so it has no operands at all. What keeps the returned value
575// alive as far as this is the `ret_val` in front of it.
576static LEAVE: [OperandDesc; 0] = [];
577static VEC_TO_VEC: [OperandDesc; 2] = [OperandDesc::write(XMM), OperandDesc::read(XMM)];
578static LOAD_VEC: [OperandDesc; 1] = [OperandDesc::write(XMM)];
579static STORE_VEC: [OperandDesc; 1] = [OperandDesc::read(XMM)];
580// The same shape as `TWO_ADDRESS_RR` in the other class, and separate for the same reason the
581// three moves above are separate from the ones over them.
582static TWO_ADDRESS_VEC: [OperandDesc; 3] = [
583    OperandDesc::write(XMM).with(Constraint::Reuse(1)),
584    OperandDesc::read(XMM),
585    OperandDesc::read(XMM),
586];
587// A float comes back in `xmm0` on both of this machine's conventions, so the register is written
588// here for the reason `RET_VAL` gives, and the same test holds it against both of them.
589static RET_VAL_VEC: [OperandDesc; 1] = [OperandDesc::read(XMM).with(Constraint::Fixed(xmm(0)))];
590// [`RET_VAL_2`] in the other file, and `xmm1` for the same reason `rdx` is.
591static RET_VAL_2_VEC: [OperandDesc; 1] = [OperandDesc::read(XMM).with(Constraint::Fixed(xmm(1)))];
592static ARG_VAL_VEC: [OperandDesc; 1] = [OperandDesc::write(XMM)];
593// The two shapes that cross the files, which are the first operand lists here whose two entries
594// are not drawn from the same one. Nothing else about them is new: a conversion writes a register
595// it did not read, the same way `movzbq` does.
596static GPR_TO_VEC: [OperandDesc; 2] = [OperandDesc::write(XMM), OperandDesc::read(GPR)];
597static VEC_TO_GPR: [OperandDesc; 2] = [OperandDesc::write(GPR), OperandDesc::read(XMM)];
598// `TWO_TO_ONE` with the two sources in the other file, which is what comparing two floats and
599// setting a byte on the answer is.
600static VEC_TO_ONE: [OperandDesc; 3] =
601    [OperandDesc::write(GPR), OperandDesc::read(XMM), OperandDesc::read(XMM)];
602// The same with the spare byte the two conditions that take two `setcc` need. It is a definition
603// rather than a fixed register so that the allocator places it, and it is a definition at all so
604// that the allocator knows the instruction lands a value there: two definitions of one instruction
605// are live at the same point, so the register this gets is never the register the answer gets.
606static VEC_TO_ONE_BOTH: [OperandDesc; 4] = [
607    OperandDesc::write(GPR),
608    OperandDesc::write(GPR),
609    OperandDesc::read(XMM),
610    OperandDesc::read(XMM),
611];
612
613// An x87 instruction names nothing at all. Every other instruction here has at least one operand
614// because it has at least one end in a register the allocator picked, and these have no end there:
615// where one is an addressing mode the builder appends its registers, and everywhere else it is a
616// depth on a stack nothing allocates from. So the operand vector of one of these holds exactly the
617// registers of its address, and for the ones with no address it is empty.
618static X87_MEM: [OperandDesc; 0] = [];
619// The one exception, which is the comparison, because a truth value is a byte and a byte is not
620// something the x87 holds. `VEC_TO_ONE` with the two sources gone: they are on the stack, and the
621// stack is not somewhere an operand can point.
622static X87_TO_ONE: [OperandDesc; 1] = [OperandDesc::write(GPR)];
623static X87_TO_ONE_BOTH: [OperandDesc; 2] = [OperandDesc::write(GPR), OperandDesc::write(GPR)];
624
625impl Form {
626    /// The operands of an instruction of this form, the ones it writes before the ones it
627    /// reads.
628    ///
629    /// The registers an addressing mode names are not here. They are operands and the allocator
630    /// rewrites them like any other, and `rucc_mir::InstBuilder::mem` is what puts them in the
631    /// vector, because the addressing mode holds their positions and a caller that had to keep
632    /// those positions right by hand would eventually not.
633    #[must_use]
634    pub fn operands(self) -> &'static [OperandDesc] {
635        match self {
636            LoadImm => &LOAD_IMM,
637            AluRr => &TWO_ADDRESS_RR,
638            AluRi | UnaryR | ShiftRi => &TWO_ADDRESS_RI,
639            ShiftCl => &SHIFT_CL,
640            CmpSet => &TWO_TO_ONE,
641            CmpSetRi => &ONE_TO_ONE,
642            Cmp => &CMP,
643            CmpRi => &CMP_RI,
644            Convert => &ONE_TO_ONE,
645            DivQuo => &DIV_QUO,
646            DivRem => &DIV_REM,
647            Lea => &ADDRESS,
648            Load => &LOAD,
649            Store => &STORE,
650            RetVal => &RET_VAL,
651            RetVal2 => &RET_VAL_2,
652            ArgVal => &ARG_VAL,
653            BrCond => &BR_COND,
654            Call => &CALL,
655            Test => &TEST,
656            TestCmov => &TEST_CMOV,
657            Jcc | Jmp => &JUMP,
658            Move => &ONE_TO_ONE,
659            Push => &PUSH,
660            Pop => &POP,
661            Ret | Barrier | Probe | Landing | Nop => &LEAVE,
662            CmpXchg => &CMPXCHG,
663            Rmw => &READ_MODIFY_WRITE,
664            MoveVec => &VEC_TO_VEC,
665            LoadVec => &LOAD_VEC,
666            StoreVec => &STORE_VEC,
667            AluVec => &TWO_ADDRESS_VEC,
668            RetValVec => &RET_VAL_VEC,
669            RetVal2Vec => &RET_VAL_2_VEC,
670            ArgValVec => &ARG_VAL_VEC,
671            ConvertVec => &VEC_TO_VEC,
672            ConvertToVec => &GPR_TO_VEC,
673            ConvertFromVec => &VEC_TO_GPR,
674            CmpSetVec => &VEC_TO_ONE,
675            CmpSetVecBoth => &VEC_TO_ONE_BOTH,
676            PushX87 | PopX87 | CtrlX87 | ArithX87 | UnaryX87 => &X87_MEM,
677            CmpSetX87 => &X87_TO_ONE,
678            CmpSetX87Both => &X87_TO_ONE_BOTH,
679        }
680    }
681
682    /// Whether an instruction of this form carries an immediate.
683    #[must_use]
684    pub fn takes_imm(self) -> bool {
685        matches!(self, LoadImm | AluRi | ShiftRi | CmpSetRi | CmpRi | Probe)
686    }
687
688    /// Whether an instruction of this form carries an addressing mode.
689    #[must_use]
690    pub fn takes_mem(self) -> bool {
691        matches!(
692            self,
693            Lea | Load
694                | Store
695                | LoadVec
696                | StoreVec
697                | PushX87
698                | PopX87
699                | CtrlX87
700                | CmpXchg
701                | Rmw
702                | Probe
703        )
704    }
705}
706
707/// Every opcode the x86-64 rule set can produce, and the form of each.
708///
709/// Grouped by family and by width rather than sorted, because this is a list a person checks
710/// against a manual and the manual is organized the same way. A lookup is a scan, which is what
711/// a selector does once per instruction it emits.
712pub static INSTS: &[(&str, Form)] = &[
713    // Constants.
714    ("mov_ri_8", LoadImm),
715    ("mov_ri_16", LoadImm),
716    ("mov_ri_32", LoadImm),
717    ("mov_ri_64", LoadImm),
718    // Arithmetic, register with register.
719    ("add_rr_8", AluRr),
720    ("add_rr_16", AluRr),
721    ("add_rr_32", AluRr),
722    ("add_rr_64", AluRr),
723    ("sub_rr_8", AluRr),
724    ("sub_rr_16", AluRr),
725    ("sub_rr_32", AluRr),
726    ("sub_rr_64", AluRr),
727    ("and_rr_8", AluRr),
728    ("and_rr_16", AluRr),
729    ("and_rr_32", AluRr),
730    ("and_rr_64", AluRr),
731    ("or_rr_8", AluRr),
732    ("or_rr_16", AluRr),
733    ("or_rr_32", AluRr),
734    ("or_rr_64", AluRr),
735    ("xor_rr_8", AluRr),
736    ("xor_rr_16", AluRr),
737    ("xor_rr_32", AluRr),
738    ("xor_rr_64", AluRr),
739    ("imul_rr_8", AluRr),
740    ("imul_rr_16", AluRr),
741    ("imul_rr_32", AluRr),
742    ("imul_rr_64", AluRr),
743    // Arithmetic, register with immediate.
744    ("add_ri_8", AluRi),
745    ("add_ri_16", AluRi),
746    ("add_ri_32", AluRi),
747    ("add_ri_64", AluRi),
748    ("sub_ri_8", AluRi),
749    ("sub_ri_16", AluRi),
750    ("sub_ri_32", AluRi),
751    ("sub_ri_64", AluRi),
752    ("and_ri_8", AluRi),
753    ("and_ri_16", AluRi),
754    ("and_ri_32", AluRi),
755    ("and_ri_64", AluRi),
756    ("or_ri_8", AluRi),
757    ("or_ri_16", AluRi),
758    ("or_ri_32", AluRi),
759    ("or_ri_64", AluRi),
760    ("xor_ri_8", AluRi),
761    ("xor_ri_16", AluRi),
762    ("xor_ri_32", AluRi),
763    ("xor_ri_64", AluRi),
764    ("imul_ri_8", AluRi),
765    ("imul_ri_16", AluRi),
766    ("imul_ri_32", AluRi),
767    ("imul_ri_64", AluRi),
768    // Negation and complement.
769    ("neg_r_8", UnaryR),
770    ("neg_r_16", UnaryR),
771    ("neg_r_32", UnaryR),
772    ("neg_r_64", UnaryR),
773    ("not_r_8", UnaryR),
774    ("not_r_16", UnaryR),
775    ("not_r_32", UnaryR),
776    ("not_r_64", UnaryR),
777    // Division and remainder, signed and unsigned.
778    ("idiv_quo_8", DivQuo),
779    ("idiv_quo_16", DivQuo),
780    ("idiv_quo_32", DivQuo),
781    ("idiv_quo_64", DivQuo),
782    ("idiv_rem_8", DivRem),
783    ("idiv_rem_16", DivRem),
784    ("idiv_rem_32", DivRem),
785    ("idiv_rem_64", DivRem),
786    ("div_quo_8", DivQuo),
787    ("div_quo_16", DivQuo),
788    ("div_quo_32", DivQuo),
789    ("div_quo_64", DivQuo),
790    ("div_rem_8", DivRem),
791    ("div_rem_16", DivRem),
792    ("div_rem_32", DivRem),
793    ("div_rem_64", DivRem),
794    // Shifts by a constant.
795    ("shl_ri_8", ShiftRi),
796    ("shl_ri_16", ShiftRi),
797    ("shl_ri_32", ShiftRi),
798    ("shl_ri_64", ShiftRi),
799    ("shr_ri_8", ShiftRi),
800    ("shr_ri_16", ShiftRi),
801    ("shr_ri_32", ShiftRi),
802    ("shr_ri_64", ShiftRi),
803    ("sar_ri_8", ShiftRi),
804    ("sar_ri_16", ShiftRi),
805    ("sar_ri_32", ShiftRi),
806    ("sar_ri_64", ShiftRi),
807    // Shifts by a register, which is `cl` and nothing else.
808    ("shl_rcl_8", ShiftCl),
809    ("shl_rcl_16", ShiftCl),
810    ("shl_rcl_32", ShiftCl),
811    ("shl_rcl_64", ShiftCl),
812    ("shr_rcl_8", ShiftCl),
813    ("shr_rcl_16", ShiftCl),
814    ("shr_rcl_32", ShiftCl),
815    ("shr_rcl_64", ShiftCl),
816    ("sar_rcl_8", ShiftCl),
817    ("sar_rcl_16", ShiftCl),
818    ("sar_rcl_32", ShiftCl),
819    ("sar_rcl_64", ShiftCl),
820    // The comparisons, ten conditions at four widths.
821    ("cmp_set_e_8", CmpSet),
822    ("cmp_set_e_16", CmpSet),
823    ("cmp_set_e_32", CmpSet),
824    ("cmp_set_e_64", CmpSet),
825    ("cmp_set_ne_8", CmpSet),
826    ("cmp_set_ne_16", CmpSet),
827    ("cmp_set_ne_32", CmpSet),
828    ("cmp_set_ne_64", CmpSet),
829    ("cmp_set_l_8", CmpSet),
830    ("cmp_set_l_16", CmpSet),
831    ("cmp_set_l_32", CmpSet),
832    ("cmp_set_l_64", CmpSet),
833    ("cmp_set_le_8", CmpSet),
834    ("cmp_set_le_16", CmpSet),
835    ("cmp_set_le_32", CmpSet),
836    ("cmp_set_le_64", CmpSet),
837    ("cmp_set_g_8", CmpSet),
838    ("cmp_set_g_16", CmpSet),
839    ("cmp_set_g_32", CmpSet),
840    ("cmp_set_g_64", CmpSet),
841    ("cmp_set_ge_8", CmpSet),
842    ("cmp_set_ge_16", CmpSet),
843    ("cmp_set_ge_32", CmpSet),
844    ("cmp_set_ge_64", CmpSet),
845    ("cmp_set_b_8", CmpSet),
846    ("cmp_set_b_16", CmpSet),
847    ("cmp_set_b_32", CmpSet),
848    ("cmp_set_b_64", CmpSet),
849    ("cmp_set_be_8", CmpSet),
850    ("cmp_set_be_16", CmpSet),
851    ("cmp_set_be_32", CmpSet),
852    ("cmp_set_be_64", CmpSet),
853    ("cmp_set_a_8", CmpSet),
854    ("cmp_set_a_16", CmpSet),
855    ("cmp_set_a_32", CmpSet),
856    ("cmp_set_a_64", CmpSet),
857    ("cmp_set_ae_8", CmpSet),
858    ("cmp_set_ae_16", CmpSet),
859    ("cmp_set_ae_32", CmpSet),
860    ("cmp_set_ae_64", CmpSet),
861    // The same ten conditions against a constant, which is four comparisons in five.
862    ("cmp_set_e_ri_8", CmpSetRi),
863    ("cmp_set_e_ri_16", CmpSetRi),
864    ("cmp_set_e_ri_32", CmpSetRi),
865    ("cmp_set_e_ri_64", CmpSetRi),
866    ("cmp_set_ne_ri_8", CmpSetRi),
867    ("cmp_set_ne_ri_16", CmpSetRi),
868    ("cmp_set_ne_ri_32", CmpSetRi),
869    ("cmp_set_ne_ri_64", CmpSetRi),
870    ("cmp_set_l_ri_8", CmpSetRi),
871    ("cmp_set_l_ri_16", CmpSetRi),
872    ("cmp_set_l_ri_32", CmpSetRi),
873    ("cmp_set_l_ri_64", CmpSetRi),
874    ("cmp_set_le_ri_8", CmpSetRi),
875    ("cmp_set_le_ri_16", CmpSetRi),
876    ("cmp_set_le_ri_32", CmpSetRi),
877    ("cmp_set_le_ri_64", CmpSetRi),
878    ("cmp_set_g_ri_8", CmpSetRi),
879    ("cmp_set_g_ri_16", CmpSetRi),
880    ("cmp_set_g_ri_32", CmpSetRi),
881    ("cmp_set_g_ri_64", CmpSetRi),
882    ("cmp_set_ge_ri_8", CmpSetRi),
883    ("cmp_set_ge_ri_16", CmpSetRi),
884    ("cmp_set_ge_ri_32", CmpSetRi),
885    ("cmp_set_ge_ri_64", CmpSetRi),
886    ("cmp_set_b_ri_8", CmpSetRi),
887    ("cmp_set_b_ri_16", CmpSetRi),
888    ("cmp_set_b_ri_32", CmpSetRi),
889    ("cmp_set_b_ri_64", CmpSetRi),
890    ("cmp_set_be_ri_8", CmpSetRi),
891    ("cmp_set_be_ri_16", CmpSetRi),
892    ("cmp_set_be_ri_32", CmpSetRi),
893    ("cmp_set_be_ri_64", CmpSetRi),
894    ("cmp_set_a_ri_8", CmpSetRi),
895    ("cmp_set_a_ri_16", CmpSetRi),
896    ("cmp_set_a_ri_32", CmpSetRi),
897    ("cmp_set_a_ri_64", CmpSetRi),
898    ("cmp_set_ae_ri_8", CmpSetRi),
899    ("cmp_set_ae_ri_16", CmpSetRi),
900    ("cmp_set_ae_ri_32", CmpSetRi),
901    ("cmp_set_ae_ri_64", CmpSetRi),
902    // The conversions between widths.
903    ("movzx_8_16", Convert),
904    ("movzx_8_32", Convert),
905    ("movzx_8_64", Convert),
906    ("movzx_16_32", Convert),
907    ("movzx_16_64", Convert),
908    ("mov_32_to_64", Convert),
909    ("movsx_8_16", Convert),
910    ("movsx_8_32", Convert),
911    ("movsx_8_64", Convert),
912    ("movsx_16_32", Convert),
913    ("movsx_16_64", Convert),
914    ("movsxd_32_64", Convert),
915    // Widening a truth value, which the machine does with the byte widenings above because it
916    // has no narrower register than a byte. Separate names, because what these mean is what the
917    // instruction does to the one bit rather than to the byte holding it.
918    ("bit_to_8", Convert),
919    ("bit_to_16", Convert),
920    ("bit_to_32", Convert),
921    ("bit_to_64", Convert),
922    // And a bit out of something wider, which is the `and` against an immediate spelled again
923    // under a name that says the bit rather than the register.
924    ("bit_of_8", AluRi),
925    ("bit_of_16", AluRi),
926    ("bit_of_32", AluRi),
927    ("bit_of_64", AluRi),
928    ("low_8", Convert),
929    ("low_16", Convert),
930    ("low_32", Convert),
931    // The address computation the addressing modes are reached through.
932    ("lea_64", Lea),
933    // Reading and writing memory, at each width the machine has a `mov` for.
934    ("mov_rm_8", Load),
935    ("mov_rm_16", Load),
936    ("mov_rm_32", Load),
937    ("mov_rm_64", Load),
938    ("mov_mr_8", Store),
939    ("mov_mr_16", Store),
940    ("mov_mr_32", Store),
941    ("mov_mr_64", Store),
942    // Reading and writing a truth value, which the machine does with the byte forms above for the
943    // reason it widens one with the byte widenings. Separate names for the same reason as well.
944    ("mov_rm_bit", Load),
945    ("mov_mr_bit", Store),
946    // Touching a page without changing it, which is the whole of what a probing prologue writes.
947    ("or_mi_8", Probe),
948    // Putting the value a function gives back where the caller looks for it, which is as much of
949    // a return as a lowering rule decides.
950    ("ret_val_8", RetVal),
951    ("ret_val_16", RetVal),
952    ("ret_val_32", RetVal),
953    ("ret_val_64", RetVal),
954    // The same job for a float, which is a separate opcode rather than a wider one because the
955    // register it names is in the other file. A `float` and a `double` are both `xmm0` and are
956    // still two opcodes, so that the type a function returns survives as far as the machine IR
957    // and a listing says which of the two the program meant.
958    ("ret_val_f32", RetValVec),
959    ("ret_val_f64", RetValVec),
960    // The second half of a structure that comes back in two registers, at every width a half can
961    // be. The narrow ones are not a rounding of the wide one: the second eightbyte of a nine byte
962    // structure is one byte, and saying so is what keeps a listing honest about how much of the
963    // register the program meant.
964    ("ret_val2_8", RetVal2),
965    ("ret_val2_16", RetVal2),
966    ("ret_val2_32", RetVal2),
967    ("ret_val2_64", RetVal2),
968    ("ret_val2_f32", RetVal2Vec),
969    ("ret_val2_f64", RetVal2Vec),
970    // Naming the register an argument arrived in, which is the other half of the same job and is
971    // the one thing here no lowering rule reaches: where an argument is depends on its position
972    // and a rule pattern cannot see one.
973    ("arg_val_8", ArgVal),
974    ("arg_val_16", ArgVal),
975    ("arg_val_32", ArgVal),
976    ("arg_val_64", ArgVal),
977    ("arg_val_f32", ArgValVec),
978    ("arg_val_f64", ArgValVec),
979    // The condition a block leaves on, which is as much of a conditional branch as a lowering
980    // rule decides, since which arm falls through is the block layout's answer.
981    ("br_cond_8", BrCond),
982    // A call, which names nothing here because nothing about its operands is the same from one
983    // call to the next. Through an address it is the same instruction to the machine and a
984    // different one to the assembler, which writes the register with a star in front of it, and
985    // that is the whole of why there are two names here rather than one.
986    ("call", Call),
987    ("call_reg", Call),
988    // What a condition and the block layout come to. The test asks whether the byte a comparison
989    // wrote is zero, and the jump that follows it goes to the block's first successor when the
990    // answer is the one it names. Every condition is here twice over, once as itself and once as
991    // its opposite, because which of the two a block gets is which of its arms is laid out next
992    // and neither of them is more natural than the other.
993    // The conditional move, and the test in front of it that turns the condition byte into flags.
994    // One entry rather than two for the reason the comparisons above are one: what passes between
995    // the halves is the flags, and the flags are not something a rule can name. The eight bit form
996    // moves thirty two bits, because the machine has no conditional move narrower than sixteen and
997    // the low eight bits of the answer are decided by the low eight bits of the two arms, which is
998    // the same trade `imul_rr_8` makes one screen up.
999    ("test_cmov_ne_8", TestCmov),
1000    ("test_cmov_ne_16", TestCmov),
1001    ("test_cmov_ne_32", TestCmov),
1002    ("test_cmov_ne_64", TestCmov),
1003    ("test_rr_8", Test),
1004    // The comparison the test is taken back out in favour of, where the byte being tested came
1005    // from a comparison and nothing else wanted it. It is the comparison the byte came from with
1006    // the byte gone, so the flags it sets are the flags the pair already set, and the jump behind
1007    // it names the condition the byte was standing in for.
1008    ("cmp_rr_8", Cmp),
1009    ("cmp_rr_16", Cmp),
1010    ("cmp_rr_32", Cmp),
1011    ("cmp_rr_64", Cmp),
1012    ("cmp_ri_8", CmpRi),
1013    ("cmp_ri_16", CmpRi),
1014    ("cmp_ri_32", CmpRi),
1015    ("cmp_ri_64", CmpRi),
1016    // The ten conditions a jump can name, which are the ten a comparison can write a byte for.
1017    // Two of them are what a test of a byte against itself comes to, and the eight below are
1018    // only ever reached from a comparison the layout put the jump behind.
1019    ("jcc_e", Jcc),
1020    ("jcc_ne", Jcc),
1021    ("jcc_l", Jcc),
1022    ("jcc_le", Jcc),
1023    ("jcc_g", Jcc),
1024    ("jcc_ge", Jcc),
1025    ("jcc_b", Jcc),
1026    ("jcc_be", Jcc),
1027    ("jcc_a", Jcc),
1028    ("jcc_ae", Jcc),
1029    ("jmp", Jmp),
1030    // What a copy, a prologue, an epilogue, a spill and a reload are made of, which is the other
1031    // set of instructions no rule reaches. The arithmetic and the address computation a frame
1032    // needs are already above, because a prologue taking its frame is the same instruction as a
1033    // subtraction the program wrote and the encoder should not have two answers for it.
1034    ("mov_rr_64", Move),
1035    ("push_64", Push),
1036    ("pop_64", Pop),
1037    ("ret", Ret),
1038    // The barrier, which is the whole of what an ordering costs on this machine. `crate::expand`
1039    // in the code generator says why one instruction covers every ordering there is.
1040    ("mfence", Barrier),
1041    // The landing pad, which says an indirect branch may arrive here. A prologue writes one under
1042    // `-fcf-protection=branch` and nothing else produces one.
1043    ("endbr64", Landing),
1044    // A byte that does nothing, which `-fpatchable-function-entry=` reserves room with so that
1045    // something else can be written over it while the program runs. A prologue writes them and
1046    // nothing else produces one.
1047    ("nop", Nop),
1048    // Compare and exchange, at each width the machine has one for. It is the instruction the
1049    // whole atomic family is built on: everything the machine has no single instruction for is a
1050    // loop around one of these, and `spec/10-backend.md` section 10.2 is where that is written
1051    // down. The `lock` in front of it is a prefix rather than part of the name, which is why the
1052    // name here has none.
1053    ("cmpxchg_8", CmpXchg),
1054    ("cmpxchg_16", CmpXchg),
1055    ("cmpxchg_32", CmpXchg),
1056    ("cmpxchg_64", CmpXchg),
1057    // The read modify writes the machine has a single instruction for. An exchange with memory is
1058    // indivisible without being asked, and an add has to be asked, which is why one of the two
1059    // carries the prefix in `crate::x86_64::text` and the other does not.
1060    ("xchg_8", Rmw),
1061    ("xchg_16", Rmw),
1062    ("xchg_32", Rmw),
1063    ("xchg_64", Rmw),
1064    ("xadd_8", Rmw),
1065    ("xadd_16", Rmw),
1066    ("xadd_32", Rmw),
1067    ("xadd_64", Rmw),
1068    ("movaps_rr", MoveVec),
1069    ("movaps_rm", LoadVec),
1070    ("movaps_mr", StoreVec),
1071    // Reading one value out of memory and writing one back, which is the same two shapes as the
1072    // spill and the reload above and a different instruction: those move a whole register because
1073    // a spill slot holds whatever was in it, and these move exactly the width of the value because
1074    // that is all the program asked for.
1075    ("movss_rm", LoadVec),
1076    ("movsd_rm", LoadVec),
1077    ("movss_mr", StoreVec),
1078    ("movsd_mr", StoreVec),
1079    ("addss_rr", AluVec),
1080    ("addsd_rr", AluVec),
1081    ("subss_rr", AluVec),
1082    ("subsd_rr", AluVec),
1083    ("mulss_rr", AluVec),
1084    ("mulsd_rr", AluVec),
1085    ("divss_rr", AluVec),
1086    ("divsd_rr", AluVec),
1087    // The conversions, which are the instructions that cross between the two register files and
1088    // the two float formats. Ten of them, which is one for each pair of things a C program is
1089    // allowed to convert between here: the two formats in both directions, and each format with a
1090    // thirty two and a sixty four bit integer in both directions.
1091    ("cvtss2sd", ConvertVec),
1092    ("cvtsd2ss", ConvertVec),
1093    ("cvttss2si_32", ConvertFromVec),
1094    ("cvttss2si_64", ConvertFromVec),
1095    ("cvttsd2si_32", ConvertFromVec),
1096    ("cvttsd2si_64", ConvertFromVec),
1097    ("cvtsi2ss_32", ConvertToVec),
1098    ("cvtsi2ss_64", ConvertToVec),
1099    ("cvtsi2sd_32", ConvertToVec),
1100    ("cvtsi2sd_64", ConvertToVec),
1101    // The same bits in the other file, which is not a conversion at all: it is where the value is
1102    // kept and nothing about what it is worth. That is what a `bitcast` between an integer and a
1103    // float of the same width is, and it is the same instruction each way with the two arguments
1104    // swapped.
1105    ("movd_to_xmm", ConvertToVec),
1106    ("movq_to_xmm", ConvertToVec),
1107    ("movd_from_xmm", ConvertFromVec),
1108    ("movq_from_xmm", ConvertFromVec),
1109    // Comparing two floats, which is one instruction that writes flags and one that reads them,
1110    // the same pair the integer comparisons above are. Ten per format rather than one per
1111    // predicate, because the machine has four answers and a C program has sixteen questions: the
1112    // eight here are the eight the flags answer directly, and the two after them are the two
1113    // that take both a flag and the bit that says whether the comparison meant anything.
1114    //
1115    // The predicates that are not here are the ones that are one of these with the operands the
1116    // other way round, which is a fact about the rule rather than about the instruction.
1117    ("ucomiss_set_a", CmpSetVec),
1118    ("ucomiss_set_ae", CmpSetVec),
1119    ("ucomiss_set_b", CmpSetVec),
1120    ("ucomiss_set_be", CmpSetVec),
1121    ("ucomiss_set_e", CmpSetVec),
1122    ("ucomiss_set_ne", CmpSetVec),
1123    ("ucomiss_set_p", CmpSetVec),
1124    ("ucomiss_set_np", CmpSetVec),
1125    ("ucomiss_set_e_and_np", CmpSetVecBoth),
1126    ("ucomiss_set_ne_or_p", CmpSetVecBoth),
1127    ("ucomisd_set_a", CmpSetVec),
1128    ("ucomisd_set_ae", CmpSetVec),
1129    ("ucomisd_set_b", CmpSetVec),
1130    ("ucomisd_set_be", CmpSetVec),
1131    ("ucomisd_set_e", CmpSetVec),
1132    ("ucomisd_set_ne", CmpSetVec),
1133    ("ucomisd_set_p", CmpSetVec),
1134    ("ucomisd_set_np", CmpSetVec),
1135    ("ucomisd_set_e_and_np", CmpSetVecBoth),
1136    ("ucomisd_set_ne_or_p", CmpSetVecBoth),
1137    // Reading and writing an eighty bit float, which is the whole of how one gets to the only unit
1138    // on this machine that can do arithmetic on it and back again. There is no register to register
1139    // form and there is nothing to add here later: the x87 has no instruction that names two of its
1140    // registers by number, because it names them by depth. So a `long double` is in memory whenever
1141    // it is not being operated on, and these two are the pair of instructions that move it.
1142    //
1143    // Neither of them looks at the value it moves. `fld` of a single or a double converts, and
1144    // converting is where a signalling NaN is quieted and where a format that is not a number
1145    // raises, but at eighty bits there is nothing to convert: the machine holds the value in the
1146    // format it is already in, so the load is the bits and the store is the bits back. That is why
1147    // a copy of a `long double` is one of each of these rather than something that has to know
1148    // what was in it.
1149    ("fld_t", PushX87),
1150    ("fstp_t", PopX87),
1151    // The conversions, which on this machine are the same two instructions reading and writing a
1152    // different format rather than instructions of their own. A `float`, a `double` and an integer
1153    // become an eighty bit float by being loaded, and an eighty bit float becomes one of them by
1154    // being stored, so there is nothing here that converts between two things on the stack and
1155    // nothing that could: the stack holds one format and only one.
1156    //
1157    // Every widening is exact, which is worth saying because it is why none of these four can
1158    // round. An eighty bit float has sixty four bits of significand and fifteen of exponent, so
1159    // every `float`, every `double` and every sixty four bit integer is a value it holds outright.
1160    ("fld_s", PushX87),
1161    ("fld_l", PushX87),
1162    ("fild_l", PushX87),
1163    ("fild_ll", PushX87),
1164    // The narrowings, which round, and round the way C wants: to nearest, which is what the
1165    // control word says unless something has changed it.
1166    ("fstp_s", PopX87),
1167    ("fstp_l", PopX87),
1168    // Going to an integer is the one that does not, because C cuts towards zero and this rounds
1169    // to nearest like everything else the unit does. So these two are written inside the group
1170    // `spec/10-backend.md` section 10.8 gives, with the control word changed around them.
1171    ("fistp_l", PopX87),
1172    ("fistp_ll", PopX87),
1173    // The control word itself, saved and put back. `fnstcw` is the one instruction here that
1174    // writes memory without taking anything off the stack, and `fldcw` the one that reads memory
1175    // without putting anything on it.
1176    ("fnstcw", CtrlX87),
1177    ("fldcw", CtrlX87),
1178    // The arithmetic, which is what the unit is for and is the first thing here that does anything
1179    // to an eighty bit value rather than moving it. Two values at the top of the stack, one answer
1180    // left where they were, and nothing named: both sources and the destination are depths, so
1181    // these are the first instructions in this table that touch nothing the allocator knows about
1182    // at all, not even an address.
1183    //
1184    // Two subtractions and two divisions, because a depth cannot be swapped. Which of the two
1185    // operands is on top is decided when the code generator pushes them, and a rule that wanted
1186    // the other order has nowhere to put it, so the machine gives the other order as another
1187    // instruction. An addition and a multiplication need one each, being what they are.
1188    ("fadd_p", ArithX87),
1189    ("fsub_p", ArithX87),
1190    ("fsubr_p", ArithX87),
1191    ("fmul_p", ArithX87),
1192    ("fdiv_p", ArithX87),
1193    ("fdivr_p", ArithX87),
1194    // The sign, flipped and cleared, which are the two things this machine does to one of these
1195    // without reading it as a number. Neither rounds and neither raises, since neither looks at
1196    // what it has: a negation is the top bit inverted and an absolute value is the top bit off,
1197    // and that is true of a number, of an infinity and of a NaN alike.
1198    ("fchs", UnaryX87),
1199    ("fabs", UnaryX87),
1200    // Comparing two of them, which is ten opcodes for the reason the vector comparisons are ten:
1201    // the machine gives four answers and a C program asks sixteen questions, eight of which are
1202    // one flag and two of which are a flag and the bit that says the comparison meant anything.
1203    // The six that are not here are these with the operands the other way round, which for the
1204    // x87 is a fact about which one the code generator pushed first.
1205    ("fucomip_set_a", CmpSetX87),
1206    ("fucomip_set_ae", CmpSetX87),
1207    ("fucomip_set_b", CmpSetX87),
1208    ("fucomip_set_be", CmpSetX87),
1209    ("fucomip_set_e", CmpSetX87),
1210    ("fucomip_set_ne", CmpSetX87),
1211    ("fucomip_set_p", CmpSetX87),
1212    ("fucomip_set_np", CmpSetX87),
1213    ("fucomip_set_e_and_np", CmpSetX87Both),
1214    ("fucomip_set_ne_or_p", CmpSetX87Both),
1215];
1216
1217/// The form of the opcode of that name, or `None` for a name this target does not have.
1218///
1219/// The name is written the way the machine IR holds it, so `add_rr_32` rather than
1220/// `x64.add_rr_32`. The prefix is how a rule file says which target a term belongs to and it is
1221/// not part of the opcode.
1222#[must_use]
1223pub fn form(name: &str) -> Option<Form> {
1224    INSTS.iter().find(|(known, _)| *known == name).map(|&(_, form)| form)
1225}
1226
1227/// What an address constructor's arguments are.
1228///
1229/// An addressing mode is an argument to an instruction rather than an instruction, and a rule
1230/// file writes one as a term so that a rule can say which registers go where. The selector has
1231/// to turn that term into a machine IR memory operand, and what each constructor's arguments
1232/// mean is the same kind of target fact as [`Form`], so it is written here rather than in the
1233/// selector.
1234///
1235/// The scale and the displacement are arguments rather than part of the name because each is a
1236/// number the rule matched and the machine encodes it as a number. There is none with a symbol
1237/// yet, because the rules that would need one are the ones about a global and those are not
1238/// written.
1239///
1240/// What the arguments mean is the whole of what tells these apart, and there is deliberately no
1241/// predicate here that answers half the question: the same register is a base in one of these
1242/// and an index in another, and the same constant is a scale in one and a displacement in
1243/// another, so anything building an address out of one has to look at which it is.
1244#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1245pub enum Address {
1246    /// A base register, an index register and a scale, in that order.
1247    BaseIndexScale,
1248    /// An index register and a scale, which is an address with nothing to add it to.
1249    IndexScale,
1250    /// A base register on its own, which is what a pointer already in a register is.
1251    Base,
1252    /// A base register and a constant added to it, which is every field of a structure and
1253    /// every local reached through a frame pointer.
1254    BaseOffset,
1255}
1256
1257/// Every address constructor the x86-64 rule set can write, and what its arguments are.
1258pub static ADDRESSES: &[(&str, Address)] = &[
1259    ("amode_base_index_scale", Address::BaseIndexScale),
1260    ("amode_index_scale", Address::IndexScale),
1261    ("amode_base", Address::Base),
1262    ("amode_base_offset", Address::BaseOffset),
1263];
1264
1265/// The address constructor of that name, or `None` for a name that is not one.
1266///
1267/// This is what tells an instruction head from an address head, so a selector asks it before it
1268/// decides that a term it does not recognize is an error.
1269#[must_use]
1270pub fn address(name: &str) -> Option<Address> {
1271    ADDRESSES.iter().find(|(known, _)| *known == name).map(|&(_, kind)| kind)
1272}
1273
1274#[cfg(test)]
1275mod tests {
1276    use super::*;
1277    use crate::operand::Role;
1278    use crate::x86_64::{FRAME, SYSV, WIN64};
1279
1280    #[test]
1281    fn every_opcode_is_described_once() {
1282        let mut names: Vec<&str> = INSTS.iter().map(|&(name, _)| name).collect();
1283        let described = names.len();
1284        names.sort_unstable();
1285        names.dedup();
1286        assert_eq!(names.len(), described, "an opcode is described twice");
1287        // Every head in the model file, which is what the rule set may write and what
1288        // `rucc-verify` has an answer for. The two lists are checked against each other by
1289        // `rucc-codegen`, which is the crate that can read the rule set.
1290        assert_eq!(described, 358);
1291    }
1292
1293    #[test]
1294    fn a_shape_writes_before_it_reads() {
1295        for &(name, form) in INSTS {
1296            let operands = form.operands();
1297            let defs = operands.iter().filter(|operand| operand.role.is_def()).count();
1298            assert!(
1299                operands[..defs].iter().all(|operand| operand.role.is_def()),
1300                "{name} writes an operand after one it reads"
1301            );
1302            // An instruction that writes no register at all is one whose whole purpose is what it
1303            // does rather than what it computes. A store writes memory, a return puts a value
1304            // where the caller will look, a branch puts a condition where the jump that the
1305            // layout writes can read it, a test and a comparison set the flags, a jump goes
1306            // somewhere, a push
1307            // puts a register on the stack and leaving leaves, and a barrier is nothing but the
1308            // order it puts the accesses around it in. Everything else here computes something,
1309            // and an opcode that computes nothing and does nothing either would be an opcode
1310            // nothing has any reason to select.
1311            //
1312            // The x87 instructions are the only ones here that write no register and read no
1313            // register either. What each of them does is to the x87 stack, and the stack is not
1314            // somewhere a value may be told to live, so there is no operand to write down for the
1315            // end of a move that is not the address, and none at all for the arithmetic: both of
1316            // its sources and its answer are depths.
1317            assert!(
1318                defs > 0
1319                    || matches!(
1320                        form,
1321                        Store
1322                            | RetVal
1323                            | RetVal2
1324                            | RetValVec
1325                            | RetVal2Vec
1326                            | BrCond
1327                            | Call
1328                            | Test
1329                            | Cmp
1330                            | CmpRi
1331                            | Jcc
1332                            | Jmp
1333                            | Push
1334                            | Ret
1335                            | StoreVec
1336                            | Barrier
1337                            | PushX87
1338                            | PopX87
1339                            | CtrlX87
1340                            | ArithX87
1341                            | UnaryX87
1342                            | Probe
1343                            | Landing
1344                            | Nop
1345                    ),
1346                "{name} writes nothing and does nothing"
1347            );
1348        }
1349    }
1350
1351    #[test]
1352    fn a_two_address_form_ties_its_destination_to_its_first_source() {
1353        for form in [AluRr, AluRi, UnaryR, ShiftRi, ShiftCl, AluVec] {
1354            assert_eq!(form.operands()[0].constraint, Constraint::Reuse(1));
1355        }
1356        // The float arithmetic is in the other class throughout, which is the whole reason it is a
1357        // separate form from the integer arithmetic it is otherwise shaped exactly like.
1358        assert!(AluVec.operands().iter().all(|operand| operand.class == XMM));
1359        assert!(AluRr.operands().iter().all(|operand| operand.class == GPR));
1360        // A comparison writes a byte that has nothing to do with either operand, and a
1361        // conversion reads one width and writes another, so neither destroys its source.
1362        for form in [CmpSet, CmpSetVec, CmpSetVecBoth, Convert, LoadImm, Lea] {
1363            assert_eq!(form.operands()[0].constraint, Constraint::Reg);
1364        }
1365    }
1366
1367    #[test]
1368    fn a_division_names_the_registers_the_machine_insists_on() {
1369        let quo = DivQuo.operands();
1370        assert_eq!(quo[0].constraint, Constraint::Fixed(RAX));
1371        assert_eq!(quo[1].constraint, Constraint::Fixed(RDX));
1372        assert_eq!(quo[1].role, Role::EarlyDef, "the divisor may not be where the rest goes");
1373        assert_eq!(quo[2].constraint, Constraint::Fixed(RAX));
1374        assert_eq!(quo[3].constraint, Constraint::Reg);
1375        let rem = DivRem.operands();
1376        assert_eq!(rem[0].constraint, Constraint::Fixed(RDX));
1377        assert_eq!(rem[1].constraint, Constraint::Fixed(RAX));
1378    }
1379
1380    #[test]
1381    fn a_return_leaves_the_value_where_both_conventions_look_for_it() {
1382        // The register in the form is written down rather than read out of a convention, so this
1383        // is where the two are checked against each other. Both conventions this target has agree
1384        // about it, and one that did not would fail here rather than compile a function whose
1385        // caller reads a register nothing was put in.
1386        assert_eq!(RetVal.operands()[0].constraint, Constraint::Fixed(RAX));
1387        assert_eq!(SYSV.int_returns.first(), Some(&RAX));
1388        assert_eq!(WIN64.int_returns.first(), Some(&RAX));
1389        // It writes nothing, because the value is the caller's and this function has finished
1390        // with it.
1391        assert_eq!(RetVal.operands().len(), 1);
1392        assert!(!RetVal.takes_imm() && !RetVal.takes_mem());
1393
1394        // The same claim about a float, which comes back in the first vector register on both.
1395        assert_eq!(RetValVec.operands()[0].constraint, Constraint::Fixed(xmm(0)));
1396        assert_eq!(SYSV.sse_returns.first(), Some(&xmm(0)));
1397        assert_eq!(WIN64.sse_returns.first(), Some(&xmm(0)));
1398        assert_eq!(RetValVec.operands()[0].class, XMM);
1399    }
1400
1401    /// The second register, which only one of the two conventions has. Written down here the way
1402    /// the first one is, and held against the convention the same way, so that a convention which
1403    /// grew a different second register would fail here rather than compile a function whose
1404    /// caller reads the wrong half of a structure.
1405    #[test]
1406    fn the_second_half_of_a_structure_comes_back_where_sysv_says_it_does() {
1407        assert_eq!(RetVal2.operands()[0].constraint, Constraint::Fixed(RDX));
1408        assert_eq!(SYSV.int_returns.get(1), Some(&RDX));
1409        assert_eq!(RetVal2Vec.operands()[0].constraint, Constraint::Fixed(xmm(1)));
1410        assert_eq!(SYSV.sse_returns.get(1), Some(&xmm(1)));
1411        assert_eq!(RetVal2Vec.operands()[0].class, XMM);
1412
1413        // Windows returns a structure of more than eight bytes through a hidden pointer instead,
1414        // so it has no second register and nothing here should ever select one of these for it.
1415        assert_eq!(WIN64.int_returns.get(1), None);
1416        assert_eq!(WIN64.sse_returns.get(1), None);
1417    }
1418
1419    #[test]
1420    fn an_argument_names_no_register_because_its_position_is_what_says_which_one() {
1421        // The opposite of the return above, and deliberately so. Writing `rdi` here would be
1422        // writing down where the first SysV integer argument is and then being wrong about every
1423        // other argument and about Windows, so the register is put on the operand by the code
1424        // that knows the position.
1425        assert_eq!(ArgVal.operands()[0].constraint, Constraint::Reg);
1426        assert_eq!(ArgVal.operands()[0].role, Role::Def);
1427        assert_eq!(ArgVal.operands().len(), 1);
1428        assert!(!ArgVal.takes_imm() && !ArgVal.takes_mem());
1429
1430        assert_eq!(ArgValVec.operands()[0].constraint, Constraint::Reg);
1431        assert_eq!(ArgValVec.operands()[0].role, Role::Def);
1432        assert_eq!(ArgValVec.operands()[0].class, XMM);
1433    }
1434
1435    #[test]
1436    fn a_shift_by_a_register_wants_it_in_cl() {
1437        assert_eq!(ShiftCl.operands()[2].constraint, Constraint::Fixed(RCX));
1438        assert!(!ShiftCl.takes_imm());
1439        assert!(ShiftRi.takes_imm());
1440    }
1441
1442    #[test]
1443    fn only_the_shapes_that_carry_one_carry_an_immediate_or_an_address() {
1444        assert!(LoadImm.takes_imm() && AluRi.takes_imm() && ShiftRi.takes_imm());
1445        assert!(!AluRr.takes_imm() && !CmpSet.takes_imm() && !DivQuo.takes_imm());
1446        assert!(Lea.takes_mem());
1447        assert!(!AluRr.takes_mem() && !LoadImm.takes_mem());
1448    }
1449
1450    /// The two instructions that reach the x87 stack, and the two things about them that are not
1451    /// true of anything else here.
1452    ///
1453    /// They carry an address and no operand of their own, which is what says the end of the move
1454    /// that is not memory is not a register the allocator picked. And they are the only pair here
1455    /// where one is the only way into a place and the other is the only way out of it, which is
1456    /// what the discipline in `spec/10-backend.md` section 10.8 is written against.
1457    #[test]
1458    fn every_instruction_that_reaches_the_x87_stack_names_only_an_address() {
1459        assert_eq!(form("fld_t"), Some(PushX87));
1460        assert_eq!(form("fstp_t"), Some(PopX87));
1461        assert_eq!(form("fnstcw"), Some(CtrlX87));
1462        for shape in [PushX87, PopX87, CtrlX87] {
1463            assert!(shape.operands().is_empty(), "an x87 move names a register it did not pick");
1464            assert!(shape.takes_mem(), "an x87 move goes to or comes from memory");
1465            assert!(!shape.takes_imm());
1466        }
1467        // The arithmetic goes one further and names nothing at all, not even an address. Both of
1468        // its sources and its answer are depths on the stack, so an instruction of one of these
1469        // shapes touches nothing the allocator has any say over.
1470        assert_eq!(form("fadd_p"), Some(ArithX87));
1471        assert_eq!(form("fchs"), Some(UnaryX87));
1472        for shape in [ArithX87, UnaryX87] {
1473            assert!(shape.operands().is_empty(), "x87 arithmetic names a register it did not pick");
1474            assert!(!shape.takes_mem(), "x87 arithmetic works on what is already on the stack");
1475            assert!(!shape.takes_imm());
1476        }
1477        // The comparison is the exception, and the one operand it has is the byte it sets, which
1478        // is in the other file because a truth value is a byte and the x87 holds no bytes.
1479        assert_eq!(form("fucomip_set_e"), Some(CmpSetX87));
1480        assert_eq!(form("fucomip_set_e_and_np"), Some(CmpSetX87Both));
1481        for shape in [CmpSetX87, CmpSetX87Both] {
1482            assert!(shape.operands().iter().all(|operand| operand.role.is_def()));
1483            assert!(shape.operands().iter().all(|operand| operand.class == GPR));
1484            assert!(!shape.takes_mem());
1485        }
1486        // Nothing else here has an empty operand list and an address, and the two halves of that
1487        // are worth saying separately. A call has an empty list and no address, and every other
1488        // instruction that carries an address has an operand for the end of it that is a register.
1489        // The probe is the one exception the other way round: it has an address and an empty list,
1490        // because the register the address ends in is the stack pointer and the addressing mode is
1491        // what brings it.
1492        for &(name, shape) in INSTS {
1493            assert!(
1494                shape.operands().is_empty()
1495                    == matches!(shape, Call | Jcc | Jmp | Ret | Barrier | Probe | Landing | Nop)
1496                    || matches!(shape, PushX87 | PopX87 | CtrlX87 | ArithX87 | UnaryX87),
1497                "{name} has an empty operand list and is not one of the ones that should"
1498            );
1499        }
1500    }
1501
1502    /// The x87 instructions come in a shape that has to stay balanced, so this counts them.
1503    ///
1504    /// One way onto the stack per format a value can be read from, one way off it per format a
1505    /// value can be written to, and the control word pair that is neither. A push with no matching
1506    /// pop, or the other way round, would be a format this target can convert in one direction and
1507    /// not the other, which is the mistake that reaches a program as a `long double` that cannot be
1508    /// got back out again.
1509    #[test]
1510    fn the_ways_onto_the_x87_stack_and_off_it_are_the_same_in_number() {
1511        let count = |wanted| INSTS.iter().filter(|&&(_, shape)| shape == wanted).count();
1512        assert_eq!(count(PushX87), 5, "the extended format, two floats and two integers");
1513        assert_eq!(count(PopX87), 5, "the same five the other way");
1514        assert_eq!(count(CtrlX87), 2, "the control word saved and put back");
1515        // The arithmetic is not balanced the same way, because what it is counted against is C
1516        // rather than the stack. Four operations, two of which have an order that cannot be
1517        // swapped and so come in two.
1518        assert_eq!(count(ArithX87), 6, "an add, a multiply and a subtract and a divide each way");
1519        assert_eq!(count(UnaryX87), 2, "the sign flipped and the sign cleared");
1520        assert_eq!(count(CmpSetX87) + count(CmpSetX87Both), 10, "the ten a float comparison has");
1521    }
1522
1523    #[test]
1524    fn an_address_constructor_is_not_an_instruction() {
1525        assert_eq!(address("amode_base_index_scale"), Some(Address::BaseIndexScale));
1526        assert_eq!(address("amode_base_offset"), Some(Address::BaseOffset));
1527        assert_eq!(address("amode_base"), Some(Address::Base));
1528        assert_eq!(address("lea_64"), None);
1529        assert_eq!(form("amode_index_scale"), None);
1530    }
1531
1532    /// The block layout reads the four names out of [`crate::x86_64::BRANCH`] and writes them
1533    /// into the machine IR without ever asking what any of them is, so a name there that is not
1534    /// an opcode here would come out as an instruction nothing further along could describe. The
1535    /// forms are pinned too, because the layout writes one shape each and a name that turned out
1536    /// to be an ordinary two-address instruction would be written with no operands at all.
1537    #[test]
1538    fn every_instruction_the_block_layout_writes_is_described_here() {
1539        use crate::x86_64::BRANCH;
1540
1541        assert_eq!(BRANCH.prefix, FRAME.prefix, "one target, one prefix");
1542        assert_eq!(form(BRANCH.cond), Some(BrCond));
1543        assert_eq!(form(BRANCH.test), Some(Test));
1544        assert_eq!(form(BRANCH.if_true), Some(Jcc));
1545        assert_eq!(form(BRANCH.if_false), Some(Jcc));
1546        assert_eq!(form(BRANCH.jump), Some(Jmp));
1547        assert_ne!(BRANCH.if_true, BRANCH.if_false, "the two arms are not the same jump");
1548    }
1549
1550    /// The same claim about the other set of instructions nothing selects.
1551    ///
1552    /// `rucc_codegen::finish` reads these names out of [`crate::x86_64::FRAME`] and writes them
1553    /// into the machine IR, and until this table covered them there was nothing that could say
1554    /// what a push does with its operand. Six of the twelve names are shared with the rules, since
1555    /// a prologue taking its frame is a subtraction and a spill is a store, and the test says so
1556    /// by asking about the form rather than about which list the name came from.
1557    #[test]
1558    fn every_instruction_a_frame_is_made_of_is_described_here() {
1559        assert_eq!(form(FRAME.push), Some(Push));
1560        assert_eq!(form(FRAME.pop), Some(Pop));
1561        assert_eq!(form(FRAME.ret), Some(Ret));
1562        assert_eq!(form(FRAME.add), Some(AluRi));
1563        assert_eq!(form(FRAME.sub), Some(AluRi));
1564        assert_eq!(form(FRAME.align), Some(AluRi));
1565        assert_eq!(form(FRAME.lea), Some(Lea));
1566
1567        // One set of moves per class the allocator may spill, and the class each of them is
1568        // written for is the class the form draws its operands from.
1569        let gpr = FRAME.classes[GPR.number() as usize];
1570        assert_eq!(form(gpr.mov), Some(Move));
1571        assert_eq!(form(gpr.load), Some(Load));
1572        assert_eq!(form(gpr.store), Some(Store));
1573        let xmm = FRAME.classes[XMM.number() as usize];
1574        assert_eq!(form(xmm.mov), Some(MoveVec));
1575        assert_eq!(form(xmm.load), Some(LoadVec));
1576        assert_eq!(form(xmm.store), Some(StoreVec));
1577        assert_eq!(MoveVec.operands()[0].class, XMM);
1578        assert_eq!(Move.operands()[0].class, GPR);
1579    }
1580
1581    #[test]
1582    fn an_opcode_is_found_by_the_name_the_machine_ir_holds() {
1583        assert_eq!(form("add_rr_32"), Some(AluRr));
1584        assert_eq!(form("shl_rcl_64"), Some(ShiftCl));
1585        assert_eq!(form("lea_64"), Some(Lea));
1586        assert_eq!(form("x64.add_rr_32"), None, "the prefix is not part of the opcode");
1587        assert_eq!(form("add_rr_128"), None);
1588    }
1589}