Skip to main content

rucc_target/x86_64/
encode.rs

1//! What each x86-64 machine instruction is in bytes.
2//!
3//! Design: `spec/11-asm-objects-debug.md` section 11.1.
4//!
5//! The other half of [`crate::x86_64::written`]. That says which instructions of the machine an
6//! opcode is, what each of them is called and which operand each argument is drawn from, and this
7//! says what the bytes of one of them are. Section 11.1 asks for one description behind both the
8//! text and the object file, and this is how the two are one: a caller walks the same list of
9//! [`Written`](crate::x86_64::Written) either way and only the last step differs, so an
10//! instruction cannot be in the listing and missing from the object, or be written with one
11//! operand and encoded with another.
12//!
13//! # How a row is found
14//!
15//! By the mnemonic and by what kind of thing each of its arguments is, which is what an assembler
16//! does. `movl` is four different instructions depending on whether it is given an immediate, a
17//! register, a load or a store, and they share a mnemonic because they do the same thing rather
18//! than because they are the same instruction.
19//!
20//! The immediate is part of the question too. Two families here have a shorter form for a small
21//! number: every arithmetic instruction can sign extend one byte instead of carrying four, and
22//! the sixty four bit move is ten bytes with the whole number in it and seven with four sign
23//! extended bytes. Writing those as their own rows, in front of the general one, is what keeps
24//! the choice out of the encoder, where it would be a special case, and in the table, where it is
25//! two more lines that a person can check against a manual.
26//!
27//! # What is not chosen here
28//!
29//! The short form of a jump. Every jump and call this writes carries a four byte distance,
30//! because how far it goes is not known until every block has a place and this encodes one
31//! instruction at a time. Picking the two byte form where it fits is relaxation, which
32//! `spec/11-asm-objects-debug.md` section 11.1 describes as a pass over the whole function rather
33//! than a decision an encoder makes, and it is not written yet. The bytes are correct without it
34//! and longer than an assembler's would be.
35//!
36//! The other accumulator forms are not here either. `addl $1000, %eax` has a five byte encoding
37//! that only `eax` can use and a six byte one that any register can, and only the second is
38//! written, because the first is a size win of one byte on one register and a row that applies to
39//! one register is the kind of row a reader stops checking. A shift by one is the same trade the
40//! other way round: the machine has a form that means one and carries no count, and we write the
41//! general form with a one in it, which is a byte longer and the same instruction.
42
43use std::fmt;
44
45use crate::regs::{PhysReg, Segment};
46use crate::x86_64::text::{Arg, Width};
47
48use Fits::{Signed8, Signed32};
49use Size::{Byte, Double, DoubleQuad, Long, Quad, Single, SingleQuad, Word, WordQuad};
50
51/// What kind of thing one argument of an instruction is.
52///
53/// The coarse version of [`Arg`]: which operand a register is drawn from and how much of it is
54/// read decide what is written, and neither decides which instruction it is. What decides that is
55/// whether the argument is a register at all.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum Kind {
58    /// A register, whichever one and however much of it.
59    Reg,
60    /// A vector register, whichever one.
61    ///
62    /// Which file a register is in is part of which instruction it is, and this is the one place
63    /// that could say so: an argument here is what picks a row, and `movq %rax, %rbx` and
64    /// `movq %xmm0, %rax` are the same mnemonic with two register arguments. Nothing else about
65    /// the two tells them apart, and a lookup that could not tell them apart would encode a
66    /// conversion between the files as a copy inside one of them.
67    Vec,
68    /// An address.
69    Mem,
70    /// A number the instruction carries.
71    Imm,
72    /// Somewhere else in the program, which is what a jump and a call are given.
73    Dest,
74    /// A position on the x87 stack, which is a depth rather than a register.
75    ///
76    /// Its own kind for the reason [`Kind::Vec`] is: it is what picks a row, and a row it picked
77    /// wrongly would be a different instruction. Nothing is written from it, since every row that
78    /// takes one is a fixed opcode with the depth already in its second byte. What it is for is
79    /// the same thing every kind here is for: the x87 mnemonics that take a stack position also
80    /// have forms that take an address, and a lookup that could not tell the two apart would
81    /// encode one as the other.
82    Stack,
83}
84
85impl Kind {
86    /// What kind of argument that is.
87    #[must_use]
88    pub fn of(arg: Arg) -> Self {
89        match arg {
90            Arg::Reg(_, _) | Arg::Named(_) | Arg::Through => Kind::Reg,
91            Arg::Xmm(_) => Kind::Vec,
92            Arg::Stack(_) => Kind::Stack,
93            Arg::Mem => Kind::Mem,
94            Arg::Imm => Kind::Imm,
95            Arg::Symbol | Arg::Label => Kind::Dest,
96        }
97    }
98}
99
100/// What an instruction's prefixes say about the size of what it works on.
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub enum Size {
103    /// Eight bits, which is no prefix. A REX byte may still be needed, because the four registers
104    /// numbered four to seven are `ah`, `ch`, `dh` and `bh` as bytes without one and `spl`,
105    /// `bpl`, `sil` and `dil` with one, but that is decided by the register rather than here.
106    Byte,
107    /// Sixteen bits, which is the `0x66` prefix.
108    Word,
109    /// Thirty two bits, which is this machine's default and is no prefix either. It is also what
110    /// an instruction that is sixty four bits without being told is written as, which is a push,
111    /// a pop, a jump, a call and leaving, since telling those would be a byte that says nothing.
112    Long,
113    /// Sixty four bits, which is `REX.W`.
114    Quad,
115    /// One `float`, which is the `0xF3` prefix.
116    ///
117    /// The manual calls this a mandatory prefix rather than a size, because `0xF3` in front of an
118    /// SSE opcode is part of which instruction it is rather than a claim about how wide the
119    /// operands are: `0F 58` is `addps` and `F3 0F 58` is `addss`. It is here anyway, because
120    /// where the byte goes is what this field decides and it goes exactly where `0x66` goes, in
121    /// front of the REX byte and behind nothing.
122    Single,
123    /// One `double`, which is the `0xF2` prefix and is the same kind of thing.
124    Double,
125    /// The `0x66` prefix with `REX.W` set, which is `movq` between the two register files.
126    ///
127    /// The three below are each one of the prefixes above and the bit that means sixty four bits,
128    /// which is a combination the machine really has and nothing here could say before. They are
129    /// where the conversions between an integer and a float at sixty four bits are: `cvtsi2sdq`
130    /// is the `0xF2` prefix, because that is what makes the opcode the `double` one, and `REX.W`,
131    /// because that is what makes the integer it reads sixty four bits wide, and the two answer
132    /// different questions about the same instruction.
133    WordQuad,
134    /// The `0xF3` prefix with `REX.W` set, which is the `float` conversions at sixty four bits.
135    SingleQuad,
136    /// The `0xF2` prefix with `REX.W` set, which is the `double` ones.
137    DoubleQuad,
138}
139
140impl Size {
141    /// The byte this size puts in front of the instruction, if it puts one there at all.
142    ///
143    /// `REX.W` is not here. It is a bit in a byte the registers also write into, so it is set
144    /// where that byte is built rather than returned as a prefix of its own.
145    const fn prefix(self) -> Option<u8> {
146        match self {
147            Word | WordQuad => Some(0x66),
148            Single | SingleQuad => Some(0xF3),
149            Double | DoubleQuad => Some(0xF2),
150            Byte | Long | Quad => None,
151        }
152    }
153
154    /// Whether the REX byte's wide bit is set, which is the other half of what a size says.
155    ///
156    /// Separate from [`Size::prefix`] because the two go in different bytes and because they are
157    /// not the same question. A prefix in front of an SSE opcode says which instruction it is and
158    /// this says how wide the general purpose register in it is, which is why four of the sizes
159    /// here answer both.
160    const fn wide(self) -> bool {
161        matches!(self, Quad | WordQuad | SingleQuad | DoubleQuad)
162    }
163}
164
165/// Where the arguments of an instruction go in the byte that addresses them.
166///
167/// An index rather than the argument, for the reason [`Arg`] gives: the order an instruction is
168/// written in is not the order its operands are in, and an argument the machine needs may be one
169/// the assembler does not write.
170#[derive(Debug, Clone, Copy, PartialEq, Eq)]
171pub enum Fields {
172    /// No addressing byte at all, which is an instruction whose arguments are all in the opcode
173    /// or are the distance to somewhere else.
174    None,
175    /// The argument at that index is addressed, and the three bits beside it in the byte are more
176    /// of the opcode rather than a second register. Eight instructions share `0xF7` this way.
177    Ext {
178        /// The argument the byte addresses, which is a register or an address.
179        rm: u8,
180        /// The three bits that finish the opcode.
181        ext: u8,
182    },
183    /// The argument at `rm` is addressed and the one at `reg` is the register beside it.
184    Pair {
185        /// The argument the byte addresses, which is a register or an address.
186        rm: u8,
187        /// The argument in the register field, which is always a register.
188        reg: u8,
189    },
190    /// The low three bits of that argument's register are added to the last byte of the opcode,
191    /// which is how a push, a pop and the ten byte move name theirs.
192    Plus {
193        /// The argument whose register is in the opcode.
194        reg: u8,
195    },
196}
197
198/// The immediate an instruction carries, behind everything else it is made of.
199///
200/// Named the way the manual names them, because this is a table a person checks against one.
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub enum ImmSize {
203    /// None at all.
204    None,
205    /// One byte.
206    Ib,
207    /// Two bytes.
208    Iw,
209    /// Four bytes.
210    Id,
211    /// Eight bytes, which only the ten byte move has.
212    Io,
213    /// Four bytes of signed distance from the end of the instruction, which is what a jump and a
214    /// call carry and is filled in once the place it goes to is known.
215    Cd,
216}
217
218/// Which immediates a row is for.
219///
220/// Two jobs. It is how one instruction has more than one encoding, since the arithmetic
221/// instructions have a short form for a small number and the sixty four bit move has a long one
222/// for a big one. And it is how a number too big for any form of an instruction is refused rather
223/// than quietly cut down, which would be a compiler that writes a different program from the one
224/// it was given.
225#[derive(Debug, Clone, Copy, PartialEq, Eq)]
226pub enum Fits {
227    /// Any at all, which is what a row with no immediate takes and what the one instruction with
228    /// an eight byte immediate takes.
229    Any,
230    /// One that fits in a signed byte, which is the short form every arithmetic instruction here
231    /// has and is why the general row is written behind it.
232    Signed8,
233    /// One that fits in four signed bytes, which is as far as an instruction that sign extends
234    /// what it carries reaches. That is the seven byte form of the sixty four bit move, and it is
235    /// also every sixty four bit arithmetic instruction with an immediate, because four bytes is
236    /// the widest immediate the machine has outside that one move.
237    Signed32,
238    /// One that fits in a byte, counted either way, since a number over a hundred and twenty
239    /// seven and the negative one it would be read as are the same eight bits.
240    Byte,
241    /// One that fits in two bytes, counted either way.
242    Word,
243    /// One that fits in four bytes, counted either way.
244    Long,
245}
246
247impl Fits {
248    /// Whether this row is one that number may be written with.
249    fn holds(self, imm: i64) -> bool {
250        match self {
251            Fits::Any => true,
252            Signed8 => i8::try_from(imm).is_ok(),
253            Signed32 => i32::try_from(imm).is_ok(),
254            Fits::Byte => i8::try_from(imm).is_ok() || u8::try_from(imm).is_ok(),
255            Fits::Word => i16::try_from(imm).is_ok() || u16::try_from(imm).is_ok(),
256            Fits::Long => i32::try_from(imm).is_ok() || u32::try_from(imm).is_ok(),
257        }
258    }
259}
260
261/// One instruction of the machine, as a processor reads it.
262#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263pub struct Encoding {
264    /// The mnemonic, which is the one [`Written`](crate::x86_64::Written) carries.
265    pub mnemonic: &'static str,
266    /// What each of its arguments is, in the order they are written.
267    pub args: &'static [Kind],
268    /// Which immediates this row is for.
269    pub fits: Fits,
270    /// What the prefixes say the operands are.
271    pub size: Size,
272    /// The bytes of the opcode itself, in front of everything the arguments decide.
273    pub opcode: &'static [u8],
274    /// Where the arguments go in the byte that addresses them.
275    pub fields: Fields,
276    /// The immediate behind the rest of it.
277    pub imm: ImmSize,
278}
279
280/// One row of the table below, for an instruction that carries no immediate or that carries one
281/// of any size at all.
282const fn bytes(
283    mnemonic: &'static str,
284    args: &'static [Kind],
285    size: Size,
286    opcode: &'static [u8],
287    fields: Fields,
288    imm: ImmSize,
289) -> Encoding {
290    Encoding { mnemonic, args, fits: Fits::Any, size, opcode, fields, imm }
291}
292
293/// One row for an instruction whose immediate has to be of a certain size, which is every row
294/// here that carries one but the ten byte move.
295const fn takes(
296    mnemonic: &'static str,
297    args: &'static [Kind],
298    fits: Fits,
299    size: Size,
300    opcode: &'static [u8],
301    fields: Fields,
302    imm: ImmSize,
303) -> Encoding {
304    Encoding { mnemonic, args, fits, size, opcode, fields, imm }
305}
306
307/// An addressing byte whose spare three bits finish the opcode.
308const fn ext(rm: u8, ext: u8) -> Fields {
309    Fields::Ext { rm, ext }
310}
311
312/// An addressing byte that names two registers, or one register and an address.
313const fn pair(rm: u8, reg: u8) -> Fields {
314    Fields::Pair { rm, reg }
315}
316
317/// A register in the last byte of the opcode.
318const fn plus(reg: u8) -> Fields {
319    Fields::Plus { reg }
320}
321
322/// No addressing byte.
323const NO_MODRM: Fields = Fields::None;
324/// No immediate.
325const NO_IMM: ImmSize = ImmSize::None;
326
327// The argument lists, which are short and repeat, so they are written once and named. AT&T order
328// throughout, so the source is in front of the destination.
329static NO_ARGS: [Kind; 0] = [];
330static R: [Kind; 1] = [Kind::Reg];
331static RR: [Kind; 2] = [Kind::Reg, Kind::Reg];
332static IR: [Kind; 2] = [Kind::Imm, Kind::Reg];
333static IRR: [Kind; 3] = [Kind::Imm, Kind::Reg, Kind::Reg];
334static MR: [Kind; 2] = [Kind::Mem, Kind::Reg];
335static IM: [Kind; 2] = [Kind::Imm, Kind::Mem];
336static RM: [Kind; 2] = [Kind::Reg, Kind::Mem];
337static D: [Kind; 1] = [Kind::Dest];
338static M: [Kind; 1] = [Kind::Mem];
339// The same shapes with a vector register in them, which is a different row rather than a different
340// spelling of the same one for the reason `Kind::Vec` gives.
341static VV: [Kind; 2] = [Kind::Vec, Kind::Vec];
342static MV: [Kind; 2] = [Kind::Mem, Kind::Vec];
343static VM: [Kind; 2] = [Kind::Vec, Kind::Mem];
344static RV: [Kind; 2] = [Kind::Reg, Kind::Vec];
345static VR: [Kind; 2] = [Kind::Vec, Kind::Reg];
346// The x87 stack positions, which are one argument or two and are never anything else. There is no
347// row here mixing one with a register or with an address, because no instruction on this machine
348// names a stack position and a register in the same breath.
349static S: [Kind; 1] = [Kind::Stack];
350static SS: [Kind; 2] = [Kind::Stack, Kind::Stack];
351
352/// Every instruction [`crate::x86_64::written`] can name, and the bytes it comes out as.
353///
354/// In the order the opcodes that reach them are described in, and grouped the same way, so that
355/// a reader with the manual open can go down all three tables together. An instruction reached
356/// from more than one opcode is written once, where it is first reached, which is why the
357/// conversions hold the widening a division needs and the arithmetic holds the clearing.
358///
359/// A row for a small immediate comes in front of the general row for the same instruction,
360/// because a lookup takes the first row that fits and the narrower one is the one wanted.
361static ENCODINGS: &[Encoding] = &[
362    // Constants. The three narrow ones put the destination in the opcode rather than in an
363    // addressing byte, which is one byte shorter and is why `B0` and `B8` are here instead of
364    // `C6 /0` and `C7 /0`. The addressed forms reach memory as well and these do not, and no move
365    // here writes an immediate to memory, so the shorter row is the only row each of them needs.
366    // The sixty four bit move is the one that keeps the addressing byte: its short form carries
367    // the whole eight bytes and the addressed one sign extends four, so seven beats ten whenever
368    // the number fits, which is nearly always.
369    takes("movb", &IR, Fits::Byte, Byte, &[0xB0], plus(1), ImmSize::Ib),
370    takes("movw", &IR, Fits::Word, Word, &[0xB8], plus(1), ImmSize::Iw),
371    takes("movl", &IR, Fits::Long, Long, &[0xB8], plus(1), ImmSize::Id),
372    takes("movq", &IR, Signed32, Quad, &[0xC7], ext(1, 0), ImmSize::Id),
373    bytes("movq", &IR, Quad, &[0xB8], plus(1), ImmSize::Io),
374    // Arithmetic, register with register. The source is written first and is the register beside
375    // the addressing byte, and the destination is the one the byte addresses.
376    bytes("addb", &RR, Byte, &[0x00], pair(1, 0), NO_IMM),
377    bytes("addw", &RR, Word, &[0x01], pair(1, 0), NO_IMM),
378    bytes("addl", &RR, Long, &[0x01], pair(1, 0), NO_IMM),
379    bytes("addq", &RR, Quad, &[0x01], pair(1, 0), NO_IMM),
380    bytes("subb", &RR, Byte, &[0x28], pair(1, 0), NO_IMM),
381    bytes("subw", &RR, Word, &[0x29], pair(1, 0), NO_IMM),
382    bytes("subl", &RR, Long, &[0x29], pair(1, 0), NO_IMM),
383    bytes("subq", &RR, Quad, &[0x29], pair(1, 0), NO_IMM),
384    bytes("andb", &RR, Byte, &[0x20], pair(1, 0), NO_IMM),
385    bytes("andw", &RR, Word, &[0x21], pair(1, 0), NO_IMM),
386    bytes("andl", &RR, Long, &[0x21], pair(1, 0), NO_IMM),
387    bytes("andq", &RR, Quad, &[0x21], pair(1, 0), NO_IMM),
388    bytes("orb", &RR, Byte, &[0x08], pair(1, 0), NO_IMM),
389    bytes("orw", &RR, Word, &[0x09], pair(1, 0), NO_IMM),
390    bytes("orl", &RR, Long, &[0x09], pair(1, 0), NO_IMM),
391    bytes("orq", &RR, Quad, &[0x09], pair(1, 0), NO_IMM),
392    bytes("xorb", &RR, Byte, &[0x30], pair(1, 0), NO_IMM),
393    bytes("xorw", &RR, Word, &[0x31], pair(1, 0), NO_IMM),
394    bytes("xorl", &RR, Long, &[0x31], pair(1, 0), NO_IMM),
395    bytes("xorq", &RR, Quad, &[0x31], pair(1, 0), NO_IMM),
396    // The multiply is the other way round from the rest of them: it is not one of the eight that
397    // share an opcode column, and the register beside the addressing byte is its destination.
398    bytes("imulw", &RR, Word, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
399    bytes("imull", &RR, Long, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
400    bytes("imulq", &RR, Quad, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
401    // Arithmetic, register with immediate. The eight of these share three opcodes and are told
402    // apart by the three bits beside the register, which is the column the manual calls `/digit`.
403    // Nothing narrower than a word can sign extend a byte, since a byte is already one.
404    takes("addb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 0), ImmSize::Ib),
405    takes("addw", &IR, Signed8, Word, &[0x83], ext(1, 0), ImmSize::Ib),
406    takes("addw", &IR, Fits::Word, Word, &[0x81], ext(1, 0), ImmSize::Iw),
407    takes("addl", &IR, Signed8, Long, &[0x83], ext(1, 0), ImmSize::Ib),
408    takes("addl", &IR, Fits::Long, Long, &[0x81], ext(1, 0), ImmSize::Id),
409    takes("addq", &IR, Signed8, Quad, &[0x83], ext(1, 0), ImmSize::Ib),
410    takes("addq", &IR, Signed32, Quad, &[0x81], ext(1, 0), ImmSize::Id),
411    takes("subb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 5), ImmSize::Ib),
412    takes("subw", &IR, Signed8, Word, &[0x83], ext(1, 5), ImmSize::Ib),
413    takes("subw", &IR, Fits::Word, Word, &[0x81], ext(1, 5), ImmSize::Iw),
414    takes("subl", &IR, Signed8, Long, &[0x83], ext(1, 5), ImmSize::Ib),
415    takes("subl", &IR, Fits::Long, Long, &[0x81], ext(1, 5), ImmSize::Id),
416    takes("subq", &IR, Signed8, Quad, &[0x83], ext(1, 5), ImmSize::Ib),
417    takes("subq", &IR, Signed32, Quad, &[0x81], ext(1, 5), ImmSize::Id),
418    takes("andb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 4), ImmSize::Ib),
419    takes("andw", &IR, Signed8, Word, &[0x83], ext(1, 4), ImmSize::Ib),
420    takes("andw", &IR, Fits::Word, Word, &[0x81], ext(1, 4), ImmSize::Iw),
421    takes("andl", &IR, Signed8, Long, &[0x83], ext(1, 4), ImmSize::Ib),
422    takes("andl", &IR, Fits::Long, Long, &[0x81], ext(1, 4), ImmSize::Id),
423    takes("andq", &IR, Signed8, Quad, &[0x83], ext(1, 4), ImmSize::Ib),
424    takes("andq", &IR, Signed32, Quad, &[0x81], ext(1, 4), ImmSize::Id),
425    takes("orb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 1), ImmSize::Ib),
426    takes("orw", &IR, Signed8, Word, &[0x83], ext(1, 1), ImmSize::Ib),
427    takes("orw", &IR, Fits::Word, Word, &[0x81], ext(1, 1), ImmSize::Iw),
428    takes("orl", &IR, Signed8, Long, &[0x83], ext(1, 1), ImmSize::Ib),
429    takes("orl", &IR, Fits::Long, Long, &[0x81], ext(1, 1), ImmSize::Id),
430    takes("orq", &IR, Signed8, Quad, &[0x83], ext(1, 1), ImmSize::Ib),
431    takes("orq", &IR, Signed32, Quad, &[0x81], ext(1, 1), ImmSize::Id),
432    takes("xorb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 6), ImmSize::Ib),
433    takes("xorw", &IR, Signed8, Word, &[0x83], ext(1, 6), ImmSize::Ib),
434    takes("xorw", &IR, Fits::Word, Word, &[0x81], ext(1, 6), ImmSize::Iw),
435    takes("xorl", &IR, Signed8, Long, &[0x83], ext(1, 6), ImmSize::Ib),
436    takes("xorl", &IR, Fits::Long, Long, &[0x81], ext(1, 6), ImmSize::Id),
437    takes("xorq", &IR, Signed8, Quad, &[0x83], ext(1, 6), ImmSize::Ib),
438    takes("xorq", &IR, Signed32, Quad, &[0x81], ext(1, 6), ImmSize::Id),
439    takes("cmpb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 7), ImmSize::Ib),
440    takes("cmpw", &IR, Signed8, Word, &[0x83], ext(1, 7), ImmSize::Ib),
441    takes("cmpw", &IR, Fits::Word, Word, &[0x81], ext(1, 7), ImmSize::Iw),
442    takes("cmpl", &IR, Signed8, Long, &[0x83], ext(1, 7), ImmSize::Ib),
443    takes("cmpl", &IR, Fits::Long, Long, &[0x81], ext(1, 7), ImmSize::Id),
444    takes("cmpq", &IR, Signed8, Quad, &[0x83], ext(1, 7), ImmSize::Ib),
445    takes("cmpq", &IR, Signed32, Quad, &[0x81], ext(1, 7), ImmSize::Id),
446    // The one row that writes an immediate to an address. Every other form of the eight reaches
447    // memory too, on this machine, and none of the rest of them is here, because the only thing
448    // this compiler writes to an address without a register in hand is a probing prologue touching
449    // a page, and that is an inclusive or of zero with one byte. See `crate::frame::Probe`.
450    takes("orb", &IM, Fits::Byte, Byte, &[0x80], ext(1, 1), ImmSize::Ib),
451    // The three-operand multiply, whose source and destination are both written because they are
452    // not the same register and whose immediate narrows the same way the eight above do.
453    takes("imulw", &IRR, Signed8, Word, &[0x6B], pair(1, 2), ImmSize::Ib),
454    takes("imulw", &IRR, Fits::Word, Word, &[0x69], pair(1, 2), ImmSize::Iw),
455    takes("imull", &IRR, Signed8, Long, &[0x6B], pair(1, 2), ImmSize::Ib),
456    takes("imull", &IRR, Fits::Long, Long, &[0x69], pair(1, 2), ImmSize::Id),
457    takes("imulq", &IRR, Signed8, Quad, &[0x6B], pair(1, 2), ImmSize::Ib),
458    takes("imulq", &IRR, Signed32, Quad, &[0x69], pair(1, 2), ImmSize::Id),
459    // Negation and complement, which are two more of the eight that share `0xF7`.
460    bytes("negb", &R, Byte, &[0xF6], ext(0, 3), NO_IMM),
461    bytes("negw", &R, Word, &[0xF7], ext(0, 3), NO_IMM),
462    bytes("negl", &R, Long, &[0xF7], ext(0, 3), NO_IMM),
463    bytes("negq", &R, Quad, &[0xF7], ext(0, 3), NO_IMM),
464    bytes("notb", &R, Byte, &[0xF6], ext(0, 2), NO_IMM),
465    bytes("notw", &R, Word, &[0xF7], ext(0, 2), NO_IMM),
466    bytes("notl", &R, Long, &[0xF7], ext(0, 2), NO_IMM),
467    bytes("notq", &R, Quad, &[0xF7], ext(0, 2), NO_IMM),
468    // The four widenings a division needs, each of which is one byte and a prefix. They read one
469    // fixed register and write another and name neither, which is why they have no arguments.
470    bytes("cbtw", &NO_ARGS, Word, &[0x98], NO_MODRM, NO_IMM),
471    bytes("cwtd", &NO_ARGS, Word, &[0x99], NO_MODRM, NO_IMM),
472    bytes("cltd", &NO_ARGS, Long, &[0x99], NO_MODRM, NO_IMM),
473    bytes("cqto", &NO_ARGS, Quad, &[0x99], NO_MODRM, NO_IMM),
474    // The divisions themselves, which are the last two of the eight.
475    bytes("idivb", &R, Byte, &[0xF6], ext(0, 7), NO_IMM),
476    bytes("idivw", &R, Word, &[0xF7], ext(0, 7), NO_IMM),
477    bytes("idivl", &R, Long, &[0xF7], ext(0, 7), NO_IMM),
478    bytes("idivq", &R, Quad, &[0xF7], ext(0, 7), NO_IMM),
479    bytes("divb", &R, Byte, &[0xF6], ext(0, 6), NO_IMM),
480    bytes("divw", &R, Word, &[0xF7], ext(0, 6), NO_IMM),
481    bytes("divl", &R, Long, &[0xF7], ext(0, 6), NO_IMM),
482    bytes("divq", &R, Quad, &[0xF7], ext(0, 6), NO_IMM),
483    // Shifts by a constant, which carry one byte of count however wide the thing shifted is,
484    // because nothing shifts a register by more than sixty three places.
485    takes("shlb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 4), ImmSize::Ib),
486    takes("shlw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 4), ImmSize::Ib),
487    takes("shll", &IR, Fits::Byte, Long, &[0xC1], ext(1, 4), ImmSize::Ib),
488    takes("shlq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 4), ImmSize::Ib),
489    takes("shrb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 5), ImmSize::Ib),
490    takes("shrw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 5), ImmSize::Ib),
491    takes("shrl", &IR, Fits::Byte, Long, &[0xC1], ext(1, 5), ImmSize::Ib),
492    takes("shrq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 5), ImmSize::Ib),
493    takes("sarb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 7), ImmSize::Ib),
494    takes("sarw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 7), ImmSize::Ib),
495    takes("sarl", &IR, Fits::Byte, Long, &[0xC1], ext(1, 7), ImmSize::Ib),
496    takes("sarq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 7), ImmSize::Ib),
497    // Shifts by a count, which is written and not encoded: the machine reads it from `cl` and
498    // there is nowhere in the instruction to say so. The count is the argument at zero, and every
499    // row here addresses the argument at one.
500    bytes("shlb", &RR, Byte, &[0xD2], ext(1, 4), NO_IMM),
501    bytes("shlw", &RR, Word, &[0xD3], ext(1, 4), NO_IMM),
502    bytes("shll", &RR, Long, &[0xD3], ext(1, 4), NO_IMM),
503    bytes("shlq", &RR, Quad, &[0xD3], ext(1, 4), NO_IMM),
504    bytes("shrb", &RR, Byte, &[0xD2], ext(1, 5), NO_IMM),
505    bytes("shrw", &RR, Word, &[0xD3], ext(1, 5), NO_IMM),
506    bytes("shrl", &RR, Long, &[0xD3], ext(1, 5), NO_IMM),
507    bytes("shrq", &RR, Quad, &[0xD3], ext(1, 5), NO_IMM),
508    bytes("sarb", &RR, Byte, &[0xD2], ext(1, 7), NO_IMM),
509    bytes("sarw", &RR, Word, &[0xD3], ext(1, 7), NO_IMM),
510    bytes("sarl", &RR, Long, &[0xD3], ext(1, 7), NO_IMM),
511    bytes("sarq", &RR, Quad, &[0xD3], ext(1, 7), NO_IMM),
512    // The comparison, which is the eighth of the ones that share an opcode column and is written
513    // the same way round as the subtraction it is.
514    bytes("cmpb", &RR, Byte, &[0x38], pair(1, 0), NO_IMM),
515    bytes("cmpw", &RR, Word, &[0x39], pair(1, 0), NO_IMM),
516    bytes("cmpl", &RR, Long, &[0x39], pair(1, 0), NO_IMM),
517    bytes("cmpq", &RR, Quad, &[0x39], pair(1, 0), NO_IMM),
518    // The byte each condition sets, which is one opcode with the condition in its low four bits.
519    // The conditional move, one opcode with the condition in its low four bits, the same way the
520    // sets above are. Only the three widths the machine has: there is no eight bit conditional
521    // move and the eight bit form of `select` is written with the thirty two bit one.
522    //
523    // The operands are the other way round from every move above it. `0F 45` reads a register or
524    // memory and writes a register, so the register field is the destination, where in `88` and
525    // `89` it is the source. The mnemonic order is the same in both and only the byte after the
526    // opcode differs, which is exactly the kind of thing a table gets wrong silently.
527    bytes("cmovnew", &RR, Word, &[0x0F, 0x45], pair(0, 1), NO_IMM),
528    bytes("cmovnel", &RR, Long, &[0x0F, 0x45], pair(0, 1), NO_IMM),
529    bytes("cmovneq", &RR, Quad, &[0x0F, 0x45], pair(0, 1), NO_IMM),
530    bytes("sete", &R, Byte, &[0x0F, 0x94], ext(0, 0), NO_IMM),
531    bytes("setne", &R, Byte, &[0x0F, 0x95], ext(0, 0), NO_IMM),
532    bytes("setl", &R, Byte, &[0x0F, 0x9C], ext(0, 0), NO_IMM),
533    bytes("setle", &R, Byte, &[0x0F, 0x9E], ext(0, 0), NO_IMM),
534    bytes("setg", &R, Byte, &[0x0F, 0x9F], ext(0, 0), NO_IMM),
535    bytes("setge", &R, Byte, &[0x0F, 0x9D], ext(0, 0), NO_IMM),
536    bytes("setb", &R, Byte, &[0x0F, 0x92], ext(0, 0), NO_IMM),
537    bytes("setbe", &R, Byte, &[0x0F, 0x96], ext(0, 0), NO_IMM),
538    bytes("seta", &R, Byte, &[0x0F, 0x97], ext(0, 0), NO_IMM),
539    bytes("setae", &R, Byte, &[0x0F, 0x93], ext(0, 0), NO_IMM),
540    // The two conditions on the parity flag, which are here because a float comparison is the one
541    // thing on this machine that sets it for a reason anybody wants. It says the two operands were
542    // not ordered, which is to say one of them was a NaN.
543    bytes("setp", &R, Byte, &[0x0F, 0x9A], ext(0, 0), NO_IMM),
544    bytes("setnp", &R, Byte, &[0x0F, 0x9B], ext(0, 0), NO_IMM),
545    // The conversions between widths, which read a register and write a wider one, so the
546    // destination is the register beside the addressing byte rather than the one it addresses.
547    // How wide the source is decides the opcode and how wide the destination is decides the
548    // prefix, which is why five opcodes make eleven instructions.
549    bytes("movzbw", &RR, Word, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
550    bytes("movzbl", &RR, Long, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
551    bytes("movzbq", &RR, Quad, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
552    bytes("movzwl", &RR, Long, &[0x0F, 0xB7], pair(0, 1), NO_IMM),
553    bytes("movzwq", &RR, Quad, &[0x0F, 0xB7], pair(0, 1), NO_IMM),
554    bytes("movsbw", &RR, Word, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
555    bytes("movsbl", &RR, Long, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
556    bytes("movsbq", &RR, Quad, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
557    bytes("movswl", &RR, Long, &[0x0F, 0xBF], pair(0, 1), NO_IMM),
558    bytes("movswq", &RR, Quad, &[0x0F, 0xBF], pair(0, 1), NO_IMM),
559    bytes("movslq", &RR, Quad, &[0x63], pair(0, 1), NO_IMM),
560    // A copy between registers, which is a store to a register rather than a load from one, so it
561    // is written the same way round as the arithmetic above and not as the conversions.
562    bytes("movb", &RR, Byte, &[0x88], pair(1, 0), NO_IMM),
563    bytes("movw", &RR, Word, &[0x89], pair(1, 0), NO_IMM),
564    bytes("movl", &RR, Long, &[0x89], pair(1, 0), NO_IMM),
565    bytes("movq", &RR, Quad, &[0x89], pair(1, 0), NO_IMM),
566    // The address computation, which is the one instruction that is given an address and does not
567    // read it.
568    bytes("leaq", &MR, Quad, &[0x8D], pair(0, 1), NO_IMM),
569    // Reading and writing memory, which are one opcode apart and are the same instruction with
570    // the two ends swapped.
571    bytes("movb", &MR, Byte, &[0x8A], pair(0, 1), NO_IMM),
572    bytes("movw", &MR, Word, &[0x8B], pair(0, 1), NO_IMM),
573    bytes("movl", &MR, Long, &[0x8B], pair(0, 1), NO_IMM),
574    bytes("movq", &MR, Quad, &[0x8B], pair(0, 1), NO_IMM),
575    bytes("movb", &RM, Byte, &[0x88], pair(1, 0), NO_IMM),
576    bytes("movw", &RM, Word, &[0x89], pair(1, 0), NO_IMM),
577    bytes("movl", &RM, Long, &[0x89], pair(1, 0), NO_IMM),
578    bytes("movq", &RM, Quad, &[0x89], pair(1, 0), NO_IMM),
579    // Reading a byte and widening it in the one instruction, which is the same opcode as the
580    // register form above with a memory operand where its register was. The byte the opcode reads
581    // is a byte whether the operand is a register or an address, so the width here is the width
582    // written rather than the width read, which is what the register form says too. This is how a
583    // `_Bool` is read, and it is the only widening load, because it is the only one where the
584    // value in memory is narrower than anything that will look at it.
585    bytes("movzbl", &MR, Long, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
586    // A call, whose distance to the function it goes to is not known here.
587    bytes("call", &D, Long, &[0xE8], NO_MODRM, ImmSize::Cd),
588    // The same mnemonic through an address, which is a different row rather than a different
589    // mnemonic because a lookup here is by what the arguments are and not only by what the
590    // instruction is called. It is one of the eight that share `0xFF` and is told from the rest by
591    // the three bits beside the register. Sixty four bits without a prefix saying so, the way a
592    // jump and a push are, since there is no form of it that calls a thirty two bit address.
593    bytes("call", &R, Long, &[0xFF], ext(0, 2), NO_IMM),
594    // What a condition and the block layout come to. The test is a comparison against zero that
595    // names the same register twice, so both of its arguments are the one operand.
596    bytes("testb", &RR, Byte, &[0x84], pair(1, 0), NO_IMM),
597    // The ten conditional jumps, which are one opcode column of sixteen and are told apart by the
598    // low four bits the way the ten `setcc` above are. The low bits are the same ones: a jump on
599    // a condition and a set on it differ in the byte before, `0x8` against `0x9`, and in nothing
600    // else. A near jump reaches anywhere in the section, and the short form that fits its
601    // distance in one byte is not here because choosing it is not an encoding question: it needs
602    // the distance, the distance needs the layout, and the layout changes when a jump gets
603    // shorter. That is a pass over a whole section and `je` above has been waiting for it since
604    // before there was anything to jump on.
605    bytes("je", &D, Long, &[0x0F, 0x84], NO_MODRM, ImmSize::Cd),
606    bytes("jne", &D, Long, &[0x0F, 0x85], NO_MODRM, ImmSize::Cd),
607    bytes("jl", &D, Long, &[0x0F, 0x8C], NO_MODRM, ImmSize::Cd),
608    bytes("jle", &D, Long, &[0x0F, 0x8E], NO_MODRM, ImmSize::Cd),
609    bytes("jg", &D, Long, &[0x0F, 0x8F], NO_MODRM, ImmSize::Cd),
610    bytes("jge", &D, Long, &[0x0F, 0x8D], NO_MODRM, ImmSize::Cd),
611    bytes("jb", &D, Long, &[0x0F, 0x82], NO_MODRM, ImmSize::Cd),
612    bytes("jbe", &D, Long, &[0x0F, 0x86], NO_MODRM, ImmSize::Cd),
613    bytes("ja", &D, Long, &[0x0F, 0x87], NO_MODRM, ImmSize::Cd),
614    bytes("jae", &D, Long, &[0x0F, 0x83], NO_MODRM, ImmSize::Cd),
615    bytes("jmp", &D, Long, &[0xE9], NO_MODRM, ImmSize::Cd),
616    // What a prologue and an epilogue are made of. A push and a pop move eight bytes without
617    // being told to, so neither carries the prefix that would say so.
618    bytes("pushq", &R, Long, &[0x50], plus(0), NO_IMM),
619    bytes("popq", &R, Long, &[0x58], plus(0), NO_IMM),
620    bytes("ret", &NO_ARGS, Long, &[0xC3], NO_MODRM, NO_IMM),
621    // The barrier. Three bytes with no operands, so the last of them is written as part of the
622    // opcode rather than built: `0xF0` is the addressing byte that names no memory and no
623    // register, and there is nothing here that could choose a different one.
624    bytes("mfence", &NO_ARGS, Long, &[0x0F, 0xAE, 0xF0], NO_MODRM, NO_IMM),
625    // The landing pad, and four bytes for the same reason the barrier is three: no operands, so
626    // the addressing byte at the end of it is part of the opcode. A machine that does not check
627    // reads the whole of it as a wider `nop`, which is what makes an object built with it run
628    // everywhere rather than only where the check exists.
629    bytes("endbr64", &NO_ARGS, Long, &[0xF3, 0x0F, 0x1E, 0xFA], NO_MODRM, NO_IMM),
630    // The byte that does nothing, which is the one byte form rather than any of the longer ones.
631    // Length is what `-fpatchable-function-entry=` counts, and a patcher writing over the room it
632    // asked for wants a whole number of bytes it can start at, so the reserved space is that many
633    // one byte instructions and not the shortest sequence that adds up.
634    bytes("nop", &NO_ARGS, Long, &[0x90], NO_MODRM, NO_IMM),
635    // The lock prefix, which is a row of its own because that is what it is in the encoding: one
636    // byte in front of the instruction it applies to, and not a bit of anything the instruction
637    // itself writes. An assembler reads it the same way, so the text form is the word on a line of
638    // its own in front of the instruction, which is what an opcode with two spellings already does
639    // for a comparison and the byte it sets.
640    //
641    // No arguments, so no addressing byte and no REX, and the size is `Long` only because a row
642    // has to name one and `Long` is the size that writes no prefix at all.
643    bytes("lock", &NO_ARGS, Long, &[0xF0], NO_MODRM, NO_IMM),
644    // Compare and exchange, which is the one instruction on this machine that reads a register the
645    // program did not name: it compares what is at the address against `rax` and puts what it
646    // found there whichever way the comparison went. The byte form is one opcode below the rest,
647    // the way every other pair of a byte form and a wider one here is.
648    bytes("cmpxchgb", &RM, Byte, &[0x0F, 0xB0], pair(1, 0), NO_IMM),
649    bytes("cmpxchgw", &RM, Word, &[0x0F, 0xB1], pair(1, 0), NO_IMM),
650    bytes("cmpxchgl", &RM, Long, &[0x0F, 0xB1], pair(1, 0), NO_IMM),
651    bytes("cmpxchgq", &RM, Quad, &[0x0F, 0xB1], pair(1, 0), NO_IMM),
652    // The exchange and the exchange and add, which are the two read modify writes this machine does
653    // in one instruction. Both put the register beside the addressing byte and the object in the
654    // addressing mode, the way a compare and exchange does, and both are a byte form one opcode
655    // below a form for the three wider sizes.
656    bytes("xchgb", &RM, Byte, &[0x86], pair(1, 0), NO_IMM),
657    bytes("xchgw", &RM, Word, &[0x87], pair(1, 0), NO_IMM),
658    bytes("xchgl", &RM, Long, &[0x87], pair(1, 0), NO_IMM),
659    bytes("xchgq", &RM, Quad, &[0x87], pair(1, 0), NO_IMM),
660    bytes("xaddb", &RM, Byte, &[0x0F, 0xC0], pair(1, 0), NO_IMM),
661    bytes("xaddw", &RM, Word, &[0x0F, 0xC1], pair(1, 0), NO_IMM),
662    bytes("xaddl", &RM, Long, &[0x0F, 0xC1], pair(1, 0), NO_IMM),
663    bytes("xaddq", &RM, Quad, &[0x0F, 0xC1], pair(1, 0), NO_IMM),
664    // The vector moves, which are the same three shapes as the general purpose ones and are one
665    // opcode apart the same way.
666    bytes("movaps", &VV, Long, &[0x0F, 0x28], pair(0, 1), NO_IMM),
667    bytes("movaps", &MV, Long, &[0x0F, 0x28], pair(0, 1), NO_IMM),
668    bytes("movaps", &VM, Long, &[0x0F, 0x29], pair(1, 0), NO_IMM),
669    // A scalar move, which is the same pair of opcodes one lower and behind the prefix that says
670    // which format it is. The load is `0x10` and the store is `0x11`, the way `movaps` is `0x28`
671    // and `0x29`, and the destination is the register beside the addressing byte in both.
672    bytes("movss", &MV, Single, &[0x0F, 0x10], pair(0, 1), NO_IMM),
673    bytes("movsd", &MV, Double, &[0x0F, 0x10], pair(0, 1), NO_IMM),
674    bytes("movss", &VM, Single, &[0x0F, 0x11], pair(1, 0), NO_IMM),
675    bytes("movsd", &VM, Double, &[0x0F, 0x11], pair(1, 0), NO_IMM),
676    // Scalar arithmetic. The four opcodes are consecutive, which is worth reading as a group: add
677    // is `0x58`, multiply `0x59`, subtract `0x5C` and divide `0x5E`, and the `float` and the
678    // `double` of each are the same byte behind a different prefix. The destination is the
679    // register beside the addressing byte here, the opposite way round from the integer
680    // arithmetic, because these instructions read their addressed operand and write the other.
681    bytes("addss", &VV, Single, &[0x0F, 0x58], pair(0, 1), NO_IMM),
682    bytes("addsd", &VV, Double, &[0x0F, 0x58], pair(0, 1), NO_IMM),
683    bytes("mulss", &VV, Single, &[0x0F, 0x59], pair(0, 1), NO_IMM),
684    bytes("mulsd", &VV, Double, &[0x0F, 0x59], pair(0, 1), NO_IMM),
685    bytes("subss", &VV, Single, &[0x0F, 0x5C], pair(0, 1), NO_IMM),
686    bytes("subsd", &VV, Double, &[0x0F, 0x5C], pair(0, 1), NO_IMM),
687    bytes("divss", &VV, Single, &[0x0F, 0x5E], pair(0, 1), NO_IMM),
688    bytes("divsd", &VV, Double, &[0x0F, 0x5E], pair(0, 1), NO_IMM),
689    // One format to the other, which is one opcode with the prefix saying which way round it
690    // goes: behind `0xF3` it reads a `float` and writes a `double` and behind `0xF2` it does the
691    // opposite, because the prefix says what the instruction reads.
692    bytes("cvtss2sd", &VV, Single, &[0x0F, 0x5A], pair(0, 1), NO_IMM),
693    bytes("cvtsd2ss", &VV, Double, &[0x0F, 0x5A], pair(0, 1), NO_IMM),
694    // A float to an integer, cutting towards zero, which is the rounding C asks for and is why
695    // the mnemonic has two `t`s in it: `cvtss2si` is the one that rounds and no C conversion
696    // wants it. The prefix says which format is read and `REX.W` says how wide the integer
697    // written is, which is the pair of questions the four rows are the four answers to. The
698    // suffix on the mnemonic is what tells two of these rows apart, since a row is found by what
699    // its arguments are and both widths of the answer are a general purpose register.
700    bytes("cvttss2sil", &VR, Single, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
701    bytes("cvttss2siq", &VR, SingleQuad, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
702    bytes("cvttsd2sil", &VR, Double, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
703    bytes("cvttsd2siq", &VR, DoubleQuad, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
704    // An integer to a float, which is the same two questions the other way round and one opcode
705    // lower. The mnemonic carries the width of the integer here because the register it reads is
706    // the one the assembler cannot see in a memory form, and this table writes the suffix on
707    // every one of them so that the four read as four rather than as two written twice.
708    bytes("cvtsi2ssl", &RV, Single, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
709    bytes("cvtsi2ssq", &RV, SingleQuad, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
710    bytes("cvtsi2sdl", &RV, Double, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
711    bytes("cvtsi2sdq", &RV, DoubleQuad, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
712    // The same bits moved from one file to the other, which is what a reinterpretation is. Two
713    // opcodes, `0x6E` towards the vector register and `0x7E` away from it, and the mnemonic is
714    // the width rather than the direction because the direction is which argument is which.
715    bytes("movd", &RV, Word, &[0x0F, 0x6E], pair(0, 1), NO_IMM),
716    bytes("movq", &RV, WordQuad, &[0x0F, 0x6E], pair(0, 1), NO_IMM),
717    bytes("movd", &VR, Word, &[0x0F, 0x7E], pair(1, 0), NO_IMM),
718    bytes("movq", &VR, WordQuad, &[0x0F, 0x7E], pair(1, 0), NO_IMM),
719    // Comparing two floats and setting the flags, which is one opcode with the prefix saying which
720    // format is read: no prefix for a `float` and `0x66` for a `double`, which is the pairing the
721    // moves at the top of this group have and not the one the arithmetic has. The register beside
722    // the addressing byte is the left hand side, so the comparison reads the same way round as
723    // `cvtss2sd` and the opposite way round from `cmpl`.
724    bytes("ucomiss", &VV, Long, &[0x0F, 0x2E], pair(0, 1), NO_IMM),
725    bytes("ucomisd", &VV, Word, &[0x0F, 0x2E], pair(0, 1), NO_IMM),
726    // The two x87 instructions, which are the same opcode with a different extension in the
727    // addressing byte: `0xDB` with five is the load and with seven is the store. One argument
728    // each, because the other end of the move is the top of the x87 stack and there is nothing in
729    // the instruction that says so. No size at all, in the sense every other row here means it:
730    // the operand is ten bytes and nothing about `0xDB` is variable, so there is no prefix and no
731    // `REX.W`, and `Long` is written because that is what this table calls a row with neither.
732    bytes("fldt", &M, Long, &[0xDB], ext(0, 5), NO_IMM),
733    bytes("fstpt", &M, Long, &[0xDB], ext(0, 7), NO_IMM),
734    // The conversions, which are the same instruction reading and writing another format. The
735    // width of the operand is in the opcode byte, which is the arrangement this corner of the
736    // machine has instead of a prefix: `0xD9` is four bytes, `0xDD` is eight bytes of float,
737    // `0xDB` is four bytes of integer and `0xDF` is eight, and the extension in the addressing
738    // byte says load or store within each. That is why these rows look unlike every other row
739    // here, where a width is a prefix or a REX bit and the opcode is the operation.
740    bytes("flds", &M, Long, &[0xD9], ext(0, 0), NO_IMM),
741    bytes("fldl", &M, Long, &[0xDD], ext(0, 0), NO_IMM),
742    bytes("fildl", &M, Long, &[0xDB], ext(0, 0), NO_IMM),
743    bytes("fildll", &M, Long, &[0xDF], ext(0, 5), NO_IMM),
744    bytes("fstps", &M, Long, &[0xD9], ext(0, 3), NO_IMM),
745    bytes("fstpl", &M, Long, &[0xDD], ext(0, 3), NO_IMM),
746    bytes("fistpl", &M, Long, &[0xDB], ext(0, 3), NO_IMM),
747    bytes("fistpll", &M, Long, &[0xDF], ext(0, 7), NO_IMM),
748    // The control word, which is two bytes and is the operand of two more extensions of `0xD9`.
749    bytes("fnstcw", &M, Long, &[0xD9], ext(0, 7), NO_IMM),
750    bytes("fldcw", &M, Long, &[0xD9], ext(0, 5), NO_IMM),
751    // The arithmetic, which is the first group of rows here with no addressing byte and no
752    // register number anywhere in it. Two opcode bytes each and both of them constant: `0xDE` says
753    // the operation works on two values on the stack and pops, the low three bits of the second
754    // byte are the depth of the second value, and the rest of it says which operation. So the
755    // depth is not encoded from an argument the way a register number is, it is part of the
756    // opcode, and the argument list is here to pick the row rather than to be written out.
757    //
758    // A subtraction and a division come in two, because the machine cannot swap two depths and a
759    // rule that wanted the other order has nowhere to put it. `0xE1` against `0xE9` and `0xF1`
760    // against `0xF9` are the same operation with the operands the other way round.
761    bytes("faddp", &SS, Long, &[0xDE, 0xC1], NO_MODRM, NO_IMM),
762    bytes("fsubp", &SS, Long, &[0xDE, 0xE1], NO_MODRM, NO_IMM),
763    bytes("fsubrp", &SS, Long, &[0xDE, 0xE9], NO_MODRM, NO_IMM),
764    bytes("fmulp", &SS, Long, &[0xDE, 0xC9], NO_MODRM, NO_IMM),
765    bytes("fdivp", &SS, Long, &[0xDE, 0xF1], NO_MODRM, NO_IMM),
766    bytes("fdivrp", &SS, Long, &[0xDE, 0xF9], NO_MODRM, NO_IMM),
767    // The two that work on the top alone, which name nothing at all: there is one value they could
768    // be talking about and the opcode is the whole instruction.
769    bytes("fchs", &NO_ARGS, Long, &[0xD9, 0xE0], NO_MODRM, NO_IMM),
770    bytes("fabs", &NO_ARGS, Long, &[0xD9, 0xE1], NO_MODRM, NO_IMM),
771    // The comparison, which writes the flags this machine's conditional jumps and byte sets read
772    // rather than the status word the x87 has of its own. That is what the `i` in the middle is
773    // and it is why there is no `fnstsw` here: the older way of reading an x87 comparison is to
774    // save the status word into `ax` and pick the bits out, and the way this uses has been in the
775    // machine since the Pentium Pro and is in the baseline.
776    //
777    // The `u` says a quiet NaN is an answer rather than an exception, which is the same choice
778    // `ucomisd` is here for and no choice at all: the ordered comparison is a rule with an extra
779    // condition on it, not a second instruction.
780    bytes("fucomip", &SS, Long, &[0xDF, 0xE9], NO_MODRM, NO_IMM),
781    // The pop that throws its value away, which is how the second operand of a comparison comes
782    // off the stack. `0xDD 0xD8` is a store to the top itself, which is a store to where the value
783    // already is, so the whole of what it does is the pop on the end of it.
784    bytes("fstp", &S, Long, &[0xDD, 0xD8], NO_MODRM, NO_IMM),
785];
786
787/// The encoding of the instruction of that mnemonic, given those arguments and that immediate.
788///
789/// `None` for a mnemonic this target does not encode, for one it does encode with arguments that
790/// are not the ones it takes, and for an immediate no form of it can carry.
791///
792/// The immediate is asked for because it is part of which instruction this is: two families here
793/// have a shorter encoding for a small number, and every one of them has a largest number it can
794/// hold. Pass zero for an instruction that carries none, which is what the first row of every
795/// such mnemonic accepts anyway.
796#[must_use]
797pub fn encoding(mnemonic: &str, args: &[Kind], imm: i64) -> Option<&'static Encoding> {
798    rows(mnemonic, args).find(|row| row.fits.holds(imm))
799}
800
801/// Every row of that mnemonic with those arguments, in the order they are written.
802fn rows<'a>(mnemonic: &'a str, args: &'a [Kind]) -> impl Iterator<Item = &'static Encoding> + 'a {
803    ENCODINGS.iter().filter(move |row| row.mnemonic == mnemonic && row.args == args)
804}
805
806/// An address, with everything about it already decided.
807///
808/// The machine IR's addressing mode names its registers by where they are in the operand vector
809/// and this names them outright, because by here the allocator has run and there is an answer.
810#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
811pub struct Addr {
812    /// The register the address starts from, if there is one.
813    pub base: Option<PhysReg>,
814    /// The register added to it, if there is one. It may not be the stack pointer, which is the
815    /// number the encoding uses to say there is no index at all.
816    pub index: Option<PhysReg>,
817    /// What the index is multiplied by, which is one, two, four or eight. Ignored when there is
818    /// no index.
819    pub scale: u8,
820    /// The constant added to the rest of it.
821    pub disp: i32,
822    /// Whether the address is counted from the end of the instruction rather than from a
823    /// register, which is how a global is reached in position independent code and is the only
824    /// way this compiler reaches one. It names no register, so it has neither base nor index.
825    pub rip: bool,
826    /// Which storage the address is in, when it is not the flat one. See [`Segment`].
827    pub segment: Option<Segment>,
828}
829
830/// What one argument of an instruction turned out to be.
831#[derive(Debug, Clone, Copy, PartialEq, Eq)]
832pub enum Value {
833    /// A register, and how much of it the instruction reads or writes.
834    ///
835    /// The width is here because it is what decides whether a REX byte is needed at all: the four
836    /// registers numbered four to seven are `ah`, `ch`, `dh` and `bh` as bytes without one and
837    /// `spl`, `bpl`, `sil` and `dil` with one, so a byte instruction naming one of the second set
838    /// carries a REX byte that says nothing else.
839    Reg(PhysReg, Width),
840    /// A vector register, all of which every instruction here that names one reads or writes.
841    ///
842    /// [`Value::Reg`] in the other file, and separate for the reason [`Kind::Vec`] gives. There is
843    /// no width, because there is nothing narrower than the whole of one to name: an instruction
844    /// that works on the low four bytes of a vector register is a different opcode rather than the
845    /// same opcode at another width, which is what `movss` and `movsd` are.
846    Xmm(PhysReg),
847    /// The byte above the low byte of one of the first four registers, which on this machine is
848    /// only ever `ah`.
849    ///
850    /// It is numbered like `spl` and told apart from it by the instruction having no REX byte,
851    /// which is why an instruction with one of these may name no register that needs one.
852    High(PhysReg),
853    /// An address.
854    Mem(Addr),
855    /// The number an immediate carries.
856    Imm(i64),
857    /// Somewhere else in the program, whose distance from here is not known yet.
858    Dest,
859    /// A position on the x87 stack, which carries no number because nothing is written from it.
860    ///
861    /// [`Kind::Stack`] says the rest. The depth the instruction works at is in the opcode, and
862    /// which depth that is comes from the text table, so what is left here is the fact that an
863    /// argument was there at all, which is what the lookup needs.
864    Stack,
865}
866
867impl Value {
868    /// What kind of argument this is, which is half of what picks an encoding.
869    #[must_use]
870    pub fn kind(self) -> Kind {
871        match self {
872            Value::Reg(_, _) | Value::High(_) => Kind::Reg,
873            Value::Xmm(_) => Kind::Vec,
874            Value::Mem(_) => Kind::Mem,
875            Value::Imm(_) => Kind::Imm,
876            Value::Dest => Kind::Dest,
877            Value::Stack => Kind::Stack,
878        }
879    }
880}
881
882/// Where in an instruction something the encoder could not know goes.
883///
884/// Both are offsets into the buffer the instruction was written to rather than into the
885/// instruction, since what the caller has to do with either is patch the buffer or record a
886/// relocation against it.
887#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
888pub struct Holes {
889    /// Where the four bytes a jump or a call leaves for the distance to its target begin.
890    pub dest: Option<usize>,
891    /// Where the four bytes an address counted from the end of the instruction leaves for its
892    /// displacement begin.
893    pub rip: Option<usize>,
894}
895
896/// Why an instruction could not be encoded.
897///
898/// Every one of these is a bug in the compiler rather than anything a program could ask for, so
899/// they carry enough to say which instruction it was and nothing more.
900#[derive(Debug, Clone, PartialEq, Eq)]
901pub enum Error {
902    /// Nothing here encodes that mnemonic with those arguments.
903    Unwritten {
904        /// The mnemonic that was asked for.
905        mnemonic: String,
906        /// What its arguments were.
907        args: Vec<Kind>,
908    },
909    /// An immediate no form of that instruction can carry, which the machine cannot write and
910    /// which would be a different number if it were cut down to fit.
911    Immediate {
912        /// The mnemonic that was asked for.
913        mnemonic: String,
914        /// The number that would not fit.
915        imm: i64,
916    },
917    /// An instruction naming `ah` and also a register that cannot be named without a REX byte,
918    /// which is a pair the encoding has no way to write.
919    Crowded {
920        /// The mnemonic that was asked for.
921        mnemonic: String,
922    },
923    /// A scale that is not one of the four the machine has.
924    Scale {
925        /// What was asked for.
926        scale: u8,
927    },
928    /// The stack pointer as an index, which is the one register that cannot be one, because its
929    /// number is what the encoding uses to say there is no index.
930    Index,
931    /// An argument that is not the kind the row said it was, which cannot happen through
932    /// [`encode`] and can through a row that disagrees with itself.
933    Argument {
934        /// The mnemonic that was asked for.
935        mnemonic: String,
936        /// Which argument it was.
937        at: u8,
938    },
939}
940
941impl fmt::Display for Error {
942    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
943        match self {
944            Error::Unwritten { mnemonic, args } => {
945                write!(f, "no encoding for {mnemonic} with {} arguments {args:?}", args.len())
946            }
947            Error::Immediate { mnemonic, imm } => {
948                write!(f, "no form of {mnemonic} can carry the immediate {imm}")
949            }
950            Error::Crowded { mnemonic } => {
951                write!(f, "{mnemonic} names ah and a register that needs a rex byte")
952            }
953            Error::Scale { scale } => write!(f, "{scale} is not a scale this machine has"),
954            Error::Index => write!(f, "the stack pointer cannot be an index"),
955            Error::Argument { mnemonic, at } => {
956                write!(f, "argument {at} of {mnemonic} is not what its encoding expects")
957            }
958        }
959    }
960}
961
962impl std::error::Error for Error {}
963
964/// The bit of a REX byte that says the operands are sixty four bits.
965const REX_W: u8 = 0b1000;
966/// The bit that carries the top of the register beside the addressing byte.
967const REX_R: u8 = 0b0100;
968/// The bit that carries the top of an index register.
969const REX_X: u8 = 0b0010;
970/// The bit that carries the top of the register the addressing byte addresses, which is also the
971/// top of a base register and of a register in the opcode.
972const REX_B: u8 = 0b0001;
973
974/// Writes one instruction of the machine onto the end of `out`.
975///
976/// The values are the arguments in the order they are written, which is the order
977/// [`Written::args`](crate::x86_64::Written::args) holds them in, so a caller resolves each of
978/// those and hands the results here.
979///
980/// # Errors
981///
982/// [`Error::Unwritten`] for an instruction this does not encode, and the rest for an instruction
983/// it does encode that was handed something the machine cannot express. All of them are bugs
984/// rather than anything a program could ask for. See [`Error`].
985pub fn encode(mnemonic: &str, values: &[Value], out: &mut Vec<u8>) -> Result<Holes, Error> {
986    let args: Vec<Kind> = values.iter().map(|value| value.kind()).collect();
987    let imm = values
988        .iter()
989        .find_map(|value| match value {
990            Value::Imm(number) => Some(*number),
991            _ => None,
992        })
993        .unwrap_or(0);
994    let Some(row) = encoding(mnemonic, &args, imm) else {
995        // Which of the two it is says something different to whoever reads it. An instruction
996        // with no row at all is a hole in this description, and one whose rows are all too narrow
997        // is a lowering that produced a constant the instruction it chose cannot hold.
998        return Err(if rows(mnemonic, &args).next().is_some() {
999            Error::Immediate { mnemonic: mnemonic.to_owned(), imm }
1000        } else {
1001            Error::Unwritten { mnemonic: mnemonic.to_owned(), args }
1002        });
1003    };
1004    Writer { row, values, rex: 0, forced: false, banned: false }.write(out, imm)
1005}
1006
1007/// One instruction being written out.
1008struct Writer<'a> {
1009    row: &'a Encoding,
1010    values: &'a [Value],
1011    /// The low four bits of the REX byte, which are the tops of the register numbers.
1012    rex: u8,
1013    /// Whether a REX byte has to be written even when it would say nothing, which is what naming
1014    /// one of the four registers that are only bytes with one asks for.
1015    forced: bool,
1016    /// Whether one may not be written at all, which is what naming `ah` asks for.
1017    banned: bool,
1018}
1019
1020impl Writer<'_> {
1021    /// The whole instruction: what the arguments come to, then the bytes in the order they go in.
1022    ///
1023    /// The addressing byte and everything behind it are worked out before anything is written,
1024    /// because they are what says whether there is a REX byte and the REX byte goes in front.
1025    fn write(mut self, out: &mut Vec<u8>, imm: i64) -> Result<Holes, Error> {
1026        let mut tail = Vec::new();
1027        let mut holes = Holes::default();
1028        let mut plus = 0;
1029        match self.row.fields {
1030            Fields::None => {}
1031            Fields::Ext { rm, ext } => self.address(rm, ext, &mut tail, &mut holes)?,
1032            Fields::Pair { rm, reg } => {
1033                let reg = self.number(reg, REX_R)?;
1034                self.address(rm, reg, &mut tail, &mut holes)?;
1035            }
1036            Fields::Plus { reg } => plus = self.number(reg, REX_B)?,
1037        }
1038        if self.banned && (self.forced || self.rex != 0) {
1039            return Err(Error::Crowded { mnemonic: self.row.mnemonic.to_owned() });
1040        }
1041
1042        // Group two of the legacy prefixes, in front of everything else because that is where a
1043        // segment override goes. It says which storage the address is in, which is a fact about
1044        // the address rather than about how wide the operands are, so it is read off the address
1045        // rather than off the row.
1046        if let Some(prefix) = self.segment() {
1047            out.push(prefix);
1048        }
1049        if let Some(prefix) = self.row.size.prefix() {
1050            out.push(prefix);
1051        }
1052        let rex = if self.row.size.wide() { self.rex | REX_W } else { self.rex };
1053        if rex != 0 || (self.forced && !self.banned) {
1054            out.push(0x40 | rex);
1055        }
1056        let (last, front) = self.row.opcode.split_last().expect("an opcode is at least one byte");
1057        out.extend_from_slice(front);
1058        out.push(last + plus);
1059        // The offsets were taken against an empty buffer, so they move by however much is in
1060        // front of the addressing byte by the time it is really written.
1061        let at = out.len();
1062        for hole in [&mut holes.dest, &mut holes.rip].into_iter().flatten() {
1063            *hole += at;
1064        }
1065        out.extend_from_slice(&tail);
1066
1067        match self.row.imm {
1068            ImmSize::None => {}
1069            ImmSize::Ib => out.push(imm as u8),
1070            ImmSize::Iw => out.extend_from_slice(&(imm as u16).to_le_bytes()),
1071            ImmSize::Id => out.extend_from_slice(&(imm as u32).to_le_bytes()),
1072            ImmSize::Io => out.extend_from_slice(&imm.to_le_bytes()),
1073            ImmSize::Cd => {
1074                holes.dest = Some(out.len());
1075                out.extend_from_slice(&0i32.to_le_bytes());
1076            }
1077        }
1078        Ok(holes)
1079    }
1080
1081    /// The prefix that says the address is in a thread's own block, when one of the arguments is
1082    /// such an address. At most one argument of an instruction is an address at all.
1083    fn segment(&self) -> Option<u8> {
1084        let segment = self.values.iter().find_map(|value| match value {
1085            Value::Mem(addr) => addr.segment,
1086            _ => None,
1087        })?;
1088        Some(match segment {
1089            Segment::Fs => 0x64,
1090            Segment::Gs => 0x65,
1091        })
1092    }
1093
1094    /// The number of the register at that index, with its top bit put in the REX byte.
1095    fn number(&mut self, at: u8, bit: u8) -> Result<u8, Error> {
1096        match self.values.get(usize::from(at)) {
1097            Some(&Value::Reg(reg, width)) => {
1098                let number = reg.number();
1099                if number >= 8 {
1100                    self.rex |= bit;
1101                }
1102                // The one thing a width decides about the bytes. Every other difference between
1103                // an eight, a sixteen, a thirty two and a sixty four bit instruction is in the
1104                // opcode or in the prefixes, and those are on the row.
1105                if width == Width::Byte && (4..8).contains(&number) {
1106                    self.forced = true;
1107                }
1108                Ok(number & 7)
1109            }
1110            // A vector register is numbered the way a general purpose one is and there is no
1111            // width to look at, since the whole of it is what the instruction works on.
1112            Some(&Value::Xmm(reg)) => {
1113                let number = reg.number();
1114                if number >= 8 {
1115                    self.rex |= bit;
1116                }
1117                Ok(number & 7)
1118            }
1119            // `ah` is `al` plus four, and so are the other three, which is also why only the
1120            // first four registers have one.
1121            Some(&Value::High(reg)) if reg.number() < 4 => {
1122                self.banned = true;
1123                Ok(reg.number() + 4)
1124            }
1125            _ => Err(Error::Argument { mnemonic: self.row.mnemonic.to_owned(), at }),
1126        }
1127    }
1128
1129    /// The addressing byte and whatever follows it, which is a register or a whole address.
1130    ///
1131    /// `reg` is the three bits beside the addressed one, which is either a register that has
1132    /// already been worked out or the rest of the opcode.
1133    fn address(
1134        &mut self,
1135        at: u8,
1136        reg: u8,
1137        out: &mut Vec<u8>,
1138        holes: &mut Holes,
1139    ) -> Result<(), Error> {
1140        match self.values.get(usize::from(at)) {
1141            Some(Value::Mem(addr)) => self.mem(*addr, reg, out, holes),
1142            Some(_) => {
1143                let rm = self.number(at, REX_B)?;
1144                out.push(0b1100_0000 | (reg << 3) | rm);
1145                Ok(())
1146            }
1147            None => Err(Error::Argument { mnemonic: self.row.mnemonic.to_owned(), at }),
1148        }
1149    }
1150
1151    /// One address, as the addressing byte and the two things that can follow it.
1152    fn mem(
1153        &mut self,
1154        addr: Addr,
1155        reg: u8,
1156        out: &mut Vec<u8>,
1157        holes: &mut Holes,
1158    ) -> Result<(), Error> {
1159        // Counted from the end of the instruction, which is the one mode with no register in it
1160        // and is said by naming the base the encoding would otherwise use for no base at all.
1161        if addr.rip {
1162            out.push((reg << 3) | 0b101);
1163            holes.rip = Some(out.len());
1164            out.extend_from_slice(&addr.disp.to_le_bytes());
1165            return Ok(());
1166        }
1167
1168        let index = match addr.index {
1169            Some(index) if index.number() == 4 => return Err(Error::Index),
1170            Some(index) => {
1171                if index.number() >= 8 {
1172                    self.rex |= REX_X;
1173                }
1174                Some(index.number() & 7)
1175            }
1176            None => None,
1177        };
1178        let scale = match addr.scale {
1179            _ if index.is_none() => 0,
1180            1 => 0,
1181            2 => 1,
1182            4 => 2,
1183            8 => 3,
1184            scale => return Err(Error::Scale { scale }),
1185        };
1186        let base = addr.base.map(|base| {
1187            if base.number() >= 8 {
1188                self.rex |= REX_B;
1189            }
1190            base.number() & 7
1191        });
1192
1193        // The stack pointer's number in the addressed field means there is a second byte instead
1194        // of a register, so an address whose base really is the stack pointer needs that byte
1195        // even when it has no index. The frame pointer's number with no displacement means the
1196        // address is counted from the end of the instruction, so an address based on it always
1197        // carries a displacement, and a byte of zero is the cheapest one.
1198        let second = index.is_some() || base == Some(4) || base.is_none();
1199        let mode = match base {
1200            None => 0,
1201            Some(base) => {
1202                if addr.disp == 0 && base != 5 {
1203                    0
1204                } else if i8::try_from(addr.disp).is_ok() {
1205                    1
1206                } else {
1207                    2
1208                }
1209            }
1210        };
1211        out.push((mode << 6) | (reg << 3) | if second { 0b100 } else { base.unwrap_or(0) });
1212        if second {
1213            // Four in the index field is no index, and five in the base field with a mode of zero
1214            // is no base, which is how an address that is nothing but a number is written.
1215            out.push((scale << 6) | (index.unwrap_or(4) << 3) | base.unwrap_or(5));
1216        }
1217        match mode {
1218            0 if base.is_none() => out.extend_from_slice(&addr.disp.to_le_bytes()),
1219            0 => {}
1220            1 => out.push(addr.disp as u8),
1221            _ => out.extend_from_slice(&addr.disp.to_le_bytes()),
1222        }
1223        Ok(())
1224    }
1225}
1226
1227#[cfg(test)]
1228mod tests {
1229    use super::*;
1230    use crate::x86_64::text::written;
1231    use crate::x86_64::{INSTS, R8, R12, R13, RAX, RBP, RCX, RDX, RSI, RSP};
1232
1233    /// The bytes of that instruction, as a string a person can compare with a disassembler's.
1234    fn hex(mnemonic: &str, values: &[Value]) -> String {
1235        let mut out = Vec::new();
1236        encode(mnemonic, values, &mut out).expect("an instruction this target encodes");
1237        out.iter().map(|byte| format!("{byte:02x}")).collect::<Vec<_>>().join(" ")
1238    }
1239
1240    /// A whole register, which is what most arguments are.
1241    fn quad(reg: PhysReg) -> Value {
1242        Value::Reg(reg, Width::Quad)
1243    }
1244
1245    /// Thirty two bits of one.
1246    fn long(reg: PhysReg) -> Value {
1247        Value::Reg(reg, Width::Long)
1248    }
1249
1250    /// Sixteen bits of one.
1251    fn word(reg: PhysReg) -> Value {
1252        Value::Reg(reg, Width::Word)
1253    }
1254
1255    /// Eight bits of one.
1256    fn byte(reg: PhysReg) -> Value {
1257        Value::Reg(reg, Width::Byte)
1258    }
1259
1260    #[test]
1261    fn every_instruction_the_listing_writes_is_one_this_encodes() {
1262        // The claim `spec/11-asm-objects-debug.md` section 11.1 makes about the two paths sharing
1263        // a description. An instruction the text path writes and this cannot encode would be an
1264        // opcode that compiles under `-S` and fails to produce an object file.
1265        for &(opcode, _) in INSTS {
1266            let insts = written(opcode).expect("every described opcode is a written opcode");
1267            for inst in insts {
1268                let args: Vec<Kind> = inst.args.iter().map(|&arg| Kind::of(arg)).collect();
1269                assert!(
1270                    encoding(inst.mnemonic, &args, 0).is_some(),
1271                    "{opcode} writes {} with {args:?} and nothing encodes it",
1272                    inst.mnemonic
1273                );
1274            }
1275        }
1276    }
1277
1278    /// Numbers on both sides of every boundary any row here has.
1279    const PROBES: [i64; 11] =
1280        [0, 1, -1, 127, 128, -128, -129, 0xffff, 0x1_0000, 0x7fff_ffff, 0x1_0000_0000];
1281
1282    #[test]
1283    fn the_rows_of_one_instruction_go_from_the_smallest_immediate_to_the_largest() {
1284        // A lookup takes the first row that fits, so the order is the whole of what makes the
1285        // short forms reachable. A general row in front of a short one would leave the short one
1286        // dead, which nothing that encodes a single instruction would ever notice, and a row that
1287        // held nothing the one in front of it did not would be dead outright.
1288        for (at, row) in ENCODINGS.iter().enumerate() {
1289            for other in &ENCODINGS[at + 1..] {
1290                if other.mnemonic != row.mnemonic || other.args != row.args {
1291                    continue;
1292                }
1293                for imm in PROBES {
1294                    assert!(
1295                        !row.fits.holds(imm) || other.fits.holds(imm),
1296                        "{} takes {imm} in front of a row that does not",
1297                        row.mnemonic
1298                    );
1299                }
1300                assert!(
1301                    PROBES.iter().any(|&imm| other.fits.holds(imm) && !row.fits.holds(imm)),
1302                    "{} has a row behind another that holds no more than it",
1303                    row.mnemonic
1304                );
1305            }
1306        }
1307    }
1308
1309    #[test]
1310    fn an_immediate_no_form_of_an_instruction_can_hold_is_refused_rather_than_cut_down() {
1311        // The bug this is here for writes a program that adds a different number from the one it
1312        // was given, which nothing downstream could notice and no test of the text path could
1313        // either, since the text path writes the number out in full.
1314        let mut out = Vec::new();
1315        let big = 0x1_2345_6789;
1316        let error = encode("addq", &[Value::Imm(big), quad(RAX)], &mut out)
1317            .expect_err("more than four bytes of immediate");
1318        assert_eq!(error, Error::Immediate { mnemonic: "addq".to_owned(), imm: big });
1319        assert_eq!(out, Vec::<u8>::new());
1320        // The sixty four bit move is the one instruction that can hold it.
1321        assert!(encode("movq", &[Value::Imm(big), quad(RAX)], &mut out).is_ok());
1322        // And an immediate that fits either way round is one the machine can hold, since what it
1323        // carries is that many bits and not that many values.
1324        assert_eq!(hex("movl", &[Value::Imm(0xffff_ffff), long(RAX)]), "b8 ff ff ff ff");
1325        assert_eq!(hex("addb", &[Value::Imm(200), byte(RAX)]), "80 c0 c8");
1326        assert_eq!(hex("shlq", &[Value::Imm(63), quad(RAX)]), "48 c1 e0 3f");
1327    }
1328
1329    #[test]
1330    fn an_instruction_with_two_registers_is_the_opcode_and_one_byte_that_names_both() {
1331        // The direction that is easy to get backwards. AT&T writes the source first and the byte
1332        // that names the two puts the destination in the half the manual calls `r/m`.
1333        assert_eq!(hex("addl", &[long(RCX), long(RAX)]), "01 c8");
1334        assert_eq!(hex("addl", &[long(RAX), long(RCX)]), "01 c1");
1335        // Sixty four bits is the same instruction with a byte in front saying so.
1336        assert_eq!(hex("addq", &[quad(RCX), quad(RAX)]), "48 01 c8");
1337        // Sixteen is the same instruction with a different byte in front.
1338        let word = [Value::Reg(RCX, Width::Word), Value::Reg(RAX, Width::Word)];
1339        assert_eq!(hex("addw", &word), "66 01 c8");
1340        // And a multiply is the other way round, because it is not one of the eight that share
1341        // an opcode column.
1342        assert_eq!(hex("imull", &[long(RCX), long(RAX)]), "0f af c1");
1343    }
1344
1345    #[test]
1346    fn a_register_the_second_half_of_the_machine_added_is_named_in_the_byte_in_front() {
1347        assert_eq!(hex("addl", &[long(R8), long(RAX)]), "44 01 c0");
1348        assert_eq!(hex("addl", &[long(RAX), long(R8)]), "41 01 c0");
1349        assert_eq!(hex("addq", &[quad(R8), quad(R8)]), "4d 01 c0");
1350        assert_eq!(hex("pushq", &[quad(R12)]), "41 54");
1351        assert_eq!(hex("popq", &[quad(RAX)]), "58");
1352    }
1353
1354    /// The conditional move, whose two operands are the other way round from the text.
1355    ///
1356    /// AT&T writes the source first and the destination second, and the byte after the opcode
1357    /// names the destination in the register field and the source in the other one, which is the
1358    /// reverse of the arithmetic. Checked against what the assembler produces for the same three
1359    /// lines, which is the only way to be sure a direction is right.
1360    #[test]
1361    fn a_conditional_move_names_its_destination_in_the_register_field() {
1362        assert_eq!(hex("cmovnel", &[long(RSI), long(RAX)]), "0f 45 c6");
1363        assert_eq!(hex("cmovneq", &[quad(RSI), quad(RAX)]), "48 0f 45 c6");
1364        assert_eq!(hex("cmovnew", &[word(RSI), word(RAX)]), "66 0f 45 c6");
1365        // And the half of the register file that needs a byte in front to be named at all.
1366        assert_eq!(hex("cmovnel", &[long(R8), long(RAX)]), "41 0f 45 c0");
1367        assert_eq!(hex("cmovnel", &[long(RAX), long(R8)]), "44 0f 45 c0");
1368    }
1369
1370    #[test]
1371    fn a_byte_register_the_machine_could_not_reach_before_forces_a_byte_that_says_nothing_else() {
1372        // Without the `40` these are `%dh` and `%bh`, which is the encoding bug that produces a
1373        // program reading a register nothing was ever put in.
1374        assert_eq!(hex("movb", &[byte(RSI), byte(RAX)]), "40 88 f0");
1375        assert_eq!(hex("sete", &[byte(RSI)]), "40 0f 94 c6");
1376        assert_eq!(hex("sete", &[byte(RAX)]), "0f 94 c0");
1377        // And the one instruction that names the high byte, which may have no such byte at all.
1378        assert_eq!(hex("movb", &[Value::High(RAX), byte(RDX)]), "88 e2");
1379        let mut out = Vec::new();
1380        let error = encode("movb", &[Value::High(RAX), byte(RSI)], &mut out)
1381            .expect_err("ah and sil in one instruction");
1382        assert_eq!(error, Error::Crowded { mnemonic: "movb".to_owned() });
1383    }
1384
1385    #[test]
1386    fn an_immediate_is_written_in_as_few_bytes_as_it_fits_in() {
1387        assert_eq!(hex("addl", &[Value::Imm(1), long(RCX)]), "83 c1 01");
1388        assert_eq!(hex("addl", &[Value::Imm(-1), long(RCX)]), "83 c1 ff");
1389        assert_eq!(hex("addl", &[Value::Imm(1000), long(RCX)]), "81 c1 e8 03 00 00");
1390        assert_eq!(hex("addq", &[Value::Imm(8), quad(RSP)]), "48 83 c4 08");
1391        // The move is the one instruction with an eight byte immediate, and it is ten bytes long
1392        // when it needs one and seven when it does not.
1393        assert_eq!(hex("movq", &[Value::Imm(1), quad(RAX)]), "48 c7 c0 01 00 00 00");
1394        assert_eq!(
1395            hex("movq", &[Value::Imm(0x1_2345_6789), quad(RAX)]),
1396            "48 b8 89 67 45 23 01 00 00 00"
1397        );
1398        // A thirty two bit move of a constant is never the ten byte form, because there is no
1399        // thirty two bit register that could hold a number too big for four bytes. It is also the
1400        // one place the destination is in the opcode rather than in a byte of its own, which is
1401        // what makes it five bytes where the sixty four bit form is seven.
1402        assert_eq!(hex("movl", &[Value::Imm(1), long(RAX)]), "b8 01 00 00 00");
1403        assert_eq!(hex("movl", &[Value::Imm(1), long(RCX)]), "b9 01 00 00 00");
1404        assert_eq!(hex("movw", &[Value::Imm(1), word(RAX)]), "66 b8 01 00");
1405        assert_eq!(hex("movb", &[Value::Imm(1), byte(RCX)]), "b1 01");
1406        // A byte register the opcode has no number for without a prefix still gets the prefix,
1407        // because the register is counted the same way whichever field it lands in.
1408        assert_eq!(hex("movb", &[Value::Imm(1), byte(RSI)]), "40 b6 01");
1409    }
1410
1411    /// The eighth of the eight that share an opcode column, which is the one that keeps none of
1412    /// the answer and only the flags. Its `/digit` is seven, so the byte naming the register is
1413    /// `0xf8` plus its number rather than `0xc0` plus it, and getting that column wrong is the
1414    /// failure that writes a subtraction where a comparison was meant.
1415    #[test]
1416    fn a_comparison_against_an_immediate_is_the_eighth_column_of_the_shared_opcode() {
1417        assert_eq!(hex("cmpl", &[Value::Imm(1), long(RCX)]), "83 f9 01");
1418        assert_eq!(hex("cmpl", &[Value::Imm(-1), long(RCX)]), "83 f9 ff");
1419        assert_eq!(hex("cmpl", &[Value::Imm(1000), long(RCX)]), "81 f9 e8 03 00 00");
1420        assert_eq!(hex("cmpq", &[Value::Imm(8), quad(RSP)]), "48 83 fc 08");
1421        assert_eq!(hex("cmpq", &[Value::Imm(100_000), quad(RAX)]), "48 81 f8 a0 86 01 00");
1422        assert_eq!(hex("cmpw", &[Value::Imm(1), word(RAX)]), "66 83 f8 01");
1423        assert_eq!(hex("cmpw", &[Value::Imm(1000), word(RAX)]), "66 81 f8 e8 03");
1424        assert_eq!(hex("cmpb", &[Value::Imm(200), byte(RAX)]), "80 f8 c8");
1425        // Sixty four bits carries four bytes of immediate at the most, and a number needing more
1426        // is refused here the way it is refused for the arithmetic, rather than cut down.
1427        let mut out = Vec::new();
1428        let big = 0x1_2345_6789;
1429        let error = encode("cmpq", &[Value::Imm(big), quad(RAX)], &mut out)
1430            .expect_err("more than four bytes of immediate");
1431        assert_eq!(error, Error::Immediate { mnemonic: "cmpq".to_owned(), imm: big });
1432    }
1433
1434    #[test]
1435    fn an_address_is_the_registers_it_names_and_whatever_is_added_to_them() {
1436        // A base on its own, which is the shortest.
1437        let base = Addr { base: Some(RCX), ..Addr::default() };
1438        assert_eq!(hex("movq", &[Value::Mem(base), quad(RAX)]), "48 8b 01");
1439        // A base and a displacement, in one byte where it fits and four where it does not.
1440        let near = Addr { base: Some(RCX), disp: -16, ..Addr::default() };
1441        assert_eq!(hex("movq", &[Value::Mem(near), quad(RAX)]), "48 8b 41 f0");
1442        let far = Addr { base: Some(RCX), disp: 1000, ..Addr::default() };
1443        assert_eq!(hex("movq", &[Value::Mem(far), quad(RAX)]), "48 8b 81 e8 03 00 00");
1444        // A base, an index and a scale, which needs the second byte.
1445        let indexed =
1446            Addr { base: Some(RCX), index: Some(RDX), scale: 4, disp: -16, ..Addr::default() };
1447        assert_eq!(hex("leaq", &[Value::Mem(indexed), quad(RAX)]), "48 8d 44 91 f0");
1448        // A store is the same address with the two ends the other way round.
1449        assert_eq!(hex("movl", &[long(RAX), Value::Mem(near)]), "89 41 f0");
1450    }
1451
1452    #[test]
1453    fn the_two_registers_an_address_cannot_be_written_with_plainly_are_written_around() {
1454        // The stack pointer's number means there is a second byte rather than a register, so an
1455        // address really based on it needs that byte even with nothing to put in it.
1456        let stack = Addr { base: Some(RSP), disp: 8, ..Addr::default() };
1457        assert_eq!(hex("movq", &[Value::Mem(stack), quad(RAX)]), "48 8b 44 24 08");
1458        // And the frame pointer's number with no displacement means the address is counted from
1459        // the end of the instruction, so one based on it always carries one.
1460        let frame = Addr { base: Some(RBP), ..Addr::default() };
1461        assert_eq!(hex("movq", &[Value::Mem(frame), quad(RAX)]), "48 8b 45 00");
1462        // The same two facts hold of the registers whose low three bits are theirs.
1463        let twelve = Addr { base: Some(R12), disp: 8, ..Addr::default() };
1464        assert_eq!(hex("movq", &[Value::Mem(twelve), quad(RAX)]), "49 8b 44 24 08");
1465        let thirteen = Addr { base: Some(R13), ..Addr::default() };
1466        assert_eq!(hex("movq", &[Value::Mem(thirteen), quad(RAX)]), "49 8b 45 00");
1467        // The stack pointer is the one register that cannot be an index at all.
1468        let mut out = Vec::new();
1469        let bad = Addr { base: Some(RCX), index: Some(RSP), scale: 1, ..Addr::default() };
1470        let error = encode("leaq", &[Value::Mem(bad), quad(RAX)], &mut out)
1471            .expect_err("the stack pointer as an index");
1472        assert_eq!(error, Error::Index);
1473    }
1474
1475    #[test]
1476    fn an_address_in_a_thread_s_own_block_is_a_prefix_and_a_constant_and_no_register() {
1477        // What every protected function on this platform starts with. The prefix comes first of
1478        // everything, in front of the one that says the operands are sixty-four bits wide, and the
1479        // address itself names no register at all: `04 25` is the byte pair that means a second
1480        // addressing byte with no base and no index in it, and then four bytes of constant.
1481        let guard = Addr { segment: Some(Segment::Fs), disp: 40, ..Addr::default() };
1482        assert_eq!(hex("movq", &[Value::Mem(guard), quad(RAX)]), "64 48 8b 04 25 28 00 00 00");
1483        // The other segment, which is the same instruction with the other prefix byte.
1484        let other = Addr { segment: Some(Segment::Gs), disp: 40, ..Addr::default() };
1485        assert_eq!(hex("movq", &[Value::Mem(other), quad(RAX)]), "65 48 8b 04 25 28 00 00 00");
1486        // A register the upper eight, so that the prefix that says so is in the picture too: it
1487        // goes behind the segment and in front of nothing else, which is the order the machine
1488        // reads them in.
1489        let guard = Addr { segment: Some(Segment::Fs), disp: 40, ..Addr::default() };
1490        assert_eq!(hex("movq", &[Value::Mem(guard), quad(R12)]), "64 4c 8b 24 25 28 00 00 00");
1491    }
1492
1493    /// The one instruction here that writes a number to an address, which is a probing prologue
1494    /// touching the page it has just reached.
1495    ///
1496    /// Four bytes, and the middle two are the same pair the stack pointer always needs: its number
1497    /// in an addressing byte means there is a second byte rather than a register, and the second
1498    /// byte then says the base is the stack pointer and there is no index. The extension in the
1499    /// first of them is the one that says this is an inclusive or rather than any of the other
1500    /// seven instructions that share the opcode, and the last byte is the zero that makes it leave
1501    /// the page alone.
1502    #[test]
1503    fn the_probe_a_prologue_touches_a_page_with_is_the_shortest_write_the_machine_has() {
1504        let top = Addr { base: Some(RSP), ..Addr::default() };
1505        assert_eq!(hex("orb", &[Value::Imm(0), Value::Mem(top)]), "80 0c 24 00");
1506        // Where the loop below a large frame looks, which is the same instruction reaching further
1507        // down and carrying the displacement it needs.
1508        let down = Addr { base: Some(RSP), disp: -4096, ..Addr::default() };
1509        assert_eq!(hex("orb", &[Value::Imm(0), Value::Mem(down)]), "80 8c 24 00 f0 ff ff 00");
1510    }
1511
1512    /// The landing pad a prologue writes under `-fcf-protection=branch`.
1513    ///
1514    /// Four bytes and none of them chosen, since it has no operands: the whole of it including the
1515    /// addressing byte at the end is the opcode. The bytes matter because a machine with no check
1516    /// in it reads the same four as a wider `nop`, which is what lets one object run on a machine
1517    /// that enforces this and on one that has never heard of it.
1518    #[test]
1519    fn the_landing_pad_is_four_bytes_and_none_of_them_are_worked_out() {
1520        assert_eq!(hex("endbr64", &[]), "f3 0f 1e fa");
1521    }
1522
1523    /// The two x87 instructions, whose bytes are checked against what the assembler writes for the
1524    /// same lines rather than against the manual, the way every other group here is.
1525    ///
1526    /// They are the only instructions on this machine with one argument that is an address and no
1527    /// register argument at all, so the addressing byte carries the extension where every other
1528    /// memory instruction carries a register, and the two of them differ in nothing else.
1529    #[test]
1530    fn the_x87_load_and_store_are_one_opcode_with_two_extensions() {
1531        let base = Addr { base: Some(RCX), ..Addr::default() };
1532        assert_eq!(hex("fldt", &[Value::Mem(base)]), "db 29");
1533        assert_eq!(hex("fstpt", &[Value::Mem(base)]), "db 39");
1534        // A displacement, which is where a `long double` in a frame really is.
1535        let near = Addr { base: Some(RCX), disp: -16, ..Addr::default() };
1536        assert_eq!(hex("fldt", &[Value::Mem(near)]), "db 69 f0");
1537        let stack = Addr { base: Some(RSP), disp: 8, ..Addr::default() };
1538        assert_eq!(hex("fstpt", &[Value::Mem(stack)]), "db 7c 24 08");
1539        // The two registers an address is written around, and the one that needs a REX byte, which
1540        // is the only byte an x87 instruction has that says anything about a register at all.
1541        let frame = Addr { base: Some(RBP), ..Addr::default() };
1542        assert_eq!(hex("fldt", &[Value::Mem(frame)]), "db 6d 00");
1543        let thirteen = Addr { base: Some(R13), disp: -16, ..Addr::default() };
1544        assert_eq!(hex("fstpt", &[Value::Mem(thirteen)]), "41 db 7d f0");
1545        let indexed = Addr { base: Some(RCX), index: Some(RDX), scale: 4, ..Addr::default() };
1546        assert_eq!(hex("fldt", &[Value::Mem(indexed)]), "db 2c 91");
1547    }
1548
1549    /// The conversions, whose bytes are the part of this corner of the machine worth checking
1550    /// against the assembler rather than reading off a page.
1551    ///
1552    /// The width of the operand is in the opcode byte rather than in a prefix, which is the
1553    /// opposite of every other group here, and load and store are two extensions of the same
1554    /// byte. So a mistake in one of these is a mistake that encodes to a real instruction doing
1555    /// something else at another width, which is exactly the mistake nothing downstream catches.
1556    #[test]
1557    fn the_x87_conversions_put_the_width_in_the_opcode_and_the_direction_in_the_extension() {
1558        let base = Addr { base: Some(RCX), ..Addr::default() };
1559        let at = |mnemonic| hex(mnemonic, &[Value::Mem(base)]);
1560        // Up: four bytes of float, eight bytes of float, four of integer, eight of integer.
1561        assert_eq!(at("flds"), "d9 01");
1562        assert_eq!(at("fldl"), "dd 01");
1563        assert_eq!(at("fildl"), "db 01");
1564        assert_eq!(at("fildll"), "df 29");
1565        // Down: the same four opcodes with the extension that stores and pops.
1566        assert_eq!(at("fstps"), "d9 19");
1567        assert_eq!(at("fstpl"), "dd 19");
1568        assert_eq!(at("fistpl"), "db 19");
1569        assert_eq!(at("fistpll"), "df 39");
1570        // The control word, which is two more extensions of the byte the four byte float uses.
1571        assert_eq!(at("fnstcw"), "d9 39");
1572        assert_eq!(at("fldcw"), "d9 29");
1573        // And an address that is not the shortest one, since a frame is where all of these really
1574        // point and nothing in a frame is at the address a register holds.
1575        let frame = Addr { base: Some(RBP), disp: -16, ..Addr::default() };
1576        assert_eq!(hex("fildl", &[Value::Mem(frame)]), "db 45 f0");
1577        let stack = Addr { base: Some(RSP), disp: 8, ..Addr::default() };
1578        assert_eq!(hex("fistpll", &[Value::Mem(stack)]), "df 7c 24 08");
1579    }
1580
1581    /// The x87 arithmetic, which is two constant bytes each and nothing worked out from anything.
1582    ///
1583    /// Worth checking one by one all the same, because the second byte is where the operation and
1584    /// the depth both live and a row with the wrong one in it would assemble to a different
1585    /// instruction rather than to nothing. The bytes are what the system assembler produces for
1586    /// the same lines.
1587    #[test]
1588    fn the_x87_arithmetic_is_two_constant_bytes_with_the_operation_in_the_second() {
1589        let pair = [Value::Stack, Value::Stack];
1590        let op = |mnemonic| hex(mnemonic, &pair);
1591        assert_eq!(op("faddp"), "de c1");
1592        assert_eq!(op("fmulp"), "de c9");
1593        // The two directions, which differ in one bit of the second byte and are the whole reason
1594        // a subtraction and a division are two opcodes here and an addition is one.
1595        assert_eq!(op("fsubp"), "de e1");
1596        assert_eq!(op("fsubrp"), "de e9");
1597        assert_eq!(op("fdivp"), "de f1");
1598        assert_eq!(op("fdivrp"), "de f9");
1599        // The two that name nothing at all, not even a depth, because there is one value they
1600        // could be talking about.
1601        assert_eq!(hex("fchs", &[]), "d9 e0");
1602        assert_eq!(hex("fabs", &[]), "d9 e1");
1603        // The comparison and the pop that gets the operand it did not take off the stack.
1604        assert_eq!(op("fucomip"), "df e9");
1605        assert_eq!(hex("fstp", &[Value::Stack]), "dd d8");
1606    }
1607
1608    #[test]
1609    fn an_address_counted_from_the_end_of_the_instruction_leaves_its_displacement_open() {
1610        let global = Addr { rip: true, ..Addr::default() };
1611        let mut out = vec![0xcc];
1612        let holes = encode("movq", &[Value::Mem(global), quad(RAX)], &mut out).expect("a global");
1613        assert_eq!(out, [0xcc, 0x48, 0x8b, 0x05, 0, 0, 0, 0]);
1614        // Where the four bytes are, counted in the buffer rather than in the instruction, because
1615        // what the caller does with it is record a relocation against the buffer.
1616        assert_eq!(holes.rip, Some(4));
1617        assert_eq!(holes.dest, None);
1618    }
1619
1620    #[test]
1621    fn a_jump_leaves_the_distance_to_where_it_goes_open() {
1622        let mut out = Vec::new();
1623        let holes = encode("jmp", &[Value::Dest], &mut out).expect("a jump");
1624        assert_eq!(out, [0xe9, 0, 0, 0, 0]);
1625        assert_eq!(holes.dest, Some(1));
1626        out.clear();
1627        let holes = encode("je", &[Value::Dest], &mut out).expect("a conditional jump");
1628        assert_eq!(out, [0x0f, 0x84, 0, 0, 0, 0]);
1629        assert_eq!(holes.dest, Some(2));
1630    }
1631
1632    #[test]
1633    fn an_instruction_with_no_arguments_is_the_opcode_and_whatever_says_how_wide_it_is() {
1634        assert_eq!(hex("ret", &[]), "c3");
1635        assert_eq!(hex("cltd", &[]), "99");
1636        assert_eq!(hex("cqto", &[]), "48 99");
1637        assert_eq!(hex("cwtd", &[]), "66 99");
1638        assert_eq!(hex("cbtw", &[]), "66 98");
1639    }
1640
1641    #[test]
1642    fn a_shift_by_a_count_does_not_encode_the_count_because_the_machine_knows_where_it_is() {
1643        // Two arguments written and one encoded, which is the case that says why an argument
1644        // names an operand rather than being one.
1645        assert_eq!(hex("shlq", &[byte(RCX), quad(RAX)]), "48 d3 e0");
1646        assert_eq!(hex("sarl", &[byte(RCX), long(RCX)]), "d3 f9");
1647        assert_eq!(hex("shll", &[Value::Imm(3), long(RAX)]), "c1 e0 03");
1648    }
1649
1650    #[test]
1651    fn a_division_is_the_widening_and_then_the_instruction_that_names_only_its_divisor() {
1652        assert_eq!(hex("idivl", &[long(RCX)]), "f7 f9");
1653        assert_eq!(hex("idivq", &[quad(RSI)]), "48 f7 fe");
1654        assert_eq!(hex("divl", &[long(RCX)]), "f7 f1");
1655        assert_eq!(hex("negl", &[long(RAX)]), "f7 d8");
1656        assert_eq!(hex("notq", &[quad(RAX)]), "48 f7 d0");
1657    }
1658
1659    /// A compare and exchange, and the prefix that makes it indivisible.
1660    ///
1661    /// The prefix is a row with no arguments because that is what it is in the encoding, one byte
1662    /// in front of whatever follows it, and the instruction it applies to encodes the same either
1663    /// way. The instruction itself names the address in the r/m field and the value it would put
1664    /// there in the register field, which is the direction a store has and the reverse of the one a
1665    /// conditional move has. Checked against what the assembler makes of the same six lines.
1666    #[test]
1667    fn a_compare_and_exchange_is_the_prefix_and_then_a_store_shaped_instruction() {
1668        let at = Addr { base: Some(RAX), ..Addr::default() };
1669        assert_eq!(hex("lock", &[]), "f0");
1670        assert_eq!(hex("cmpxchgb", &[byte(RCX), Value::Mem(at)]), "0f b0 08");
1671        assert_eq!(hex("cmpxchgw", &[word(RCX), Value::Mem(at)]), "66 0f b1 08");
1672        assert_eq!(hex("cmpxchgl", &[long(RCX), Value::Mem(at)]), "0f b1 08");
1673        assert_eq!(hex("cmpxchgq", &[quad(RCX), Value::Mem(at)]), "48 0f b1 08");
1674        // The byte form reaches the second half of the register file the same way every other byte
1675        // form does, which is worth a line because the register it names is one the allocator picks
1676        // and the other one is always `rax`.
1677        assert_eq!(hex("cmpxchgb", &[byte(RSI), Value::Mem(at)]), "40 0f b0 30");
1678    }
1679
1680    /// The two read modify writes, which name their operands the way a compare and exchange does
1681    /// and are two different opcodes rather than two spellings of one. The exchange has no prefix in
1682    /// front of it, which is the machine and not an omission: an exchange with memory is indivisible
1683    /// whether the prefix is written or not. Checked against what the assembler makes of the same
1684    /// eight lines.
1685    #[test]
1686    fn a_read_modify_write_names_the_address_the_way_a_compare_and_exchange_does() {
1687        let at = Addr { base: Some(RAX), ..Addr::default() };
1688        assert_eq!(hex("xchgb", &[byte(RCX), Value::Mem(at)]), "86 08");
1689        assert_eq!(hex("xchgw", &[word(RCX), Value::Mem(at)]), "66 87 08");
1690        assert_eq!(hex("xchgl", &[long(RCX), Value::Mem(at)]), "87 08");
1691        assert_eq!(hex("xchgq", &[quad(RCX), Value::Mem(at)]), "48 87 08");
1692        assert_eq!(hex("xaddb", &[byte(RCX), Value::Mem(at)]), "0f c0 08");
1693        assert_eq!(hex("xaddw", &[word(RCX), Value::Mem(at)]), "66 0f c1 08");
1694        assert_eq!(hex("xaddl", &[long(RCX), Value::Mem(at)]), "0f c1 08");
1695        assert_eq!(hex("xaddq", &[quad(RCX), Value::Mem(at)]), "48 0f c1 08");
1696        // The byte form reaching the second half of the register file, for the reason above.
1697        assert_eq!(hex("xchgb", &[byte(RSI), Value::Mem(at)]), "40 86 30");
1698    }
1699
1700    #[test]
1701    fn a_conversion_puts_its_destination_where_the_arithmetic_puts_its_source() {
1702        assert_eq!(hex("movzbl", &[byte(RAX), long(RCX)]), "0f b6 c8");
1703        assert_eq!(hex("movsbq", &[byte(RAX), quad(RCX)]), "48 0f be c8");
1704        assert_eq!(hex("movslq", &[long(RSI), quad(RAX)]), "48 63 c6");
1705        assert_eq!(hex("movzwl", &[Value::Reg(RSI, Width::Word), long(RAX)]), "0f b7 c6");
1706    }
1707
1708    #[test]
1709    fn a_mnemonic_with_arguments_it_does_not_take_is_refused_rather_than_encoded() {
1710        let mut out = Vec::new();
1711        let error = encode("ret", &[quad(RAX)], &mut out).expect_err("a return of a register");
1712        assert_eq!(error, Error::Unwritten { mnemonic: "ret".to_owned(), args: vec![Kind::Reg] });
1713        assert_eq!(out, Vec::<u8>::new(), "nothing is written for an instruction that is refused");
1714        let error = encode("frobnicate", &[], &mut out).expect_err("no such instruction");
1715        assert!(matches!(error, Error::Unwritten { .. }), "{error}");
1716        assert_eq!(encoding("addl", &[Kind::Reg], 0), None);
1717    }
1718}