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;
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}
75
76impl Kind {
77    /// What kind of argument that is.
78    #[must_use]
79    pub fn of(arg: Arg) -> Self {
80        match arg {
81            Arg::Reg(_, _) | Arg::Named(_) | Arg::Through => Kind::Reg,
82            Arg::Xmm(_) => Kind::Vec,
83            Arg::Mem => Kind::Mem,
84            Arg::Imm => Kind::Imm,
85            Arg::Symbol | Arg::Label => Kind::Dest,
86        }
87    }
88}
89
90/// What an instruction's prefixes say about the size of what it works on.
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub enum Size {
93    /// Eight bits, which is no prefix. A REX byte may still be needed, because the four registers
94    /// numbered four to seven are `ah`, `ch`, `dh` and `bh` as bytes without one and `spl`,
95    /// `bpl`, `sil` and `dil` with one, but that is decided by the register rather than here.
96    Byte,
97    /// Sixteen bits, which is the `0x66` prefix.
98    Word,
99    /// Thirty two bits, which is this machine's default and is no prefix either. It is also what
100    /// an instruction that is sixty four bits without being told is written as, which is a push,
101    /// a pop, a jump, a call and leaving, since telling those would be a byte that says nothing.
102    Long,
103    /// Sixty four bits, which is `REX.W`.
104    Quad,
105    /// One `float`, which is the `0xF3` prefix.
106    ///
107    /// The manual calls this a mandatory prefix rather than a size, because `0xF3` in front of an
108    /// SSE opcode is part of which instruction it is rather than a claim about how wide the
109    /// operands are: `0F 58` is `addps` and `F3 0F 58` is `addss`. It is here anyway, because
110    /// where the byte goes is what this field decides and it goes exactly where `0x66` goes, in
111    /// front of the REX byte and behind nothing.
112    Single,
113    /// One `double`, which is the `0xF2` prefix and is the same kind of thing.
114    Double,
115    /// The `0x66` prefix with `REX.W` set, which is `movq` between the two register files.
116    ///
117    /// The three below are each one of the prefixes above and the bit that means sixty four bits,
118    /// which is a combination the machine really has and nothing here could say before. They are
119    /// where the conversions between an integer and a float at sixty four bits are: `cvtsi2sdq`
120    /// is the `0xF2` prefix, because that is what makes the opcode the `double` one, and `REX.W`,
121    /// because that is what makes the integer it reads sixty four bits wide, and the two answer
122    /// different questions about the same instruction.
123    WordQuad,
124    /// The `0xF3` prefix with `REX.W` set, which is the `float` conversions at sixty four bits.
125    SingleQuad,
126    /// The `0xF2` prefix with `REX.W` set, which is the `double` ones.
127    DoubleQuad,
128}
129
130impl Size {
131    /// The byte this size puts in front of the instruction, if it puts one there at all.
132    ///
133    /// `REX.W` is not here. It is a bit in a byte the registers also write into, so it is set
134    /// where that byte is built rather than returned as a prefix of its own.
135    const fn prefix(self) -> Option<u8> {
136        match self {
137            Word | WordQuad => Some(0x66),
138            Single | SingleQuad => Some(0xF3),
139            Double | DoubleQuad => Some(0xF2),
140            Byte | Long | Quad => None,
141        }
142    }
143
144    /// Whether the REX byte's wide bit is set, which is the other half of what a size says.
145    ///
146    /// Separate from [`Size::prefix`] because the two go in different bytes and because they are
147    /// not the same question. A prefix in front of an SSE opcode says which instruction it is and
148    /// this says how wide the general purpose register in it is, which is why four of the sizes
149    /// here answer both.
150    const fn wide(self) -> bool {
151        matches!(self, Quad | WordQuad | SingleQuad | DoubleQuad)
152    }
153}
154
155/// Where the arguments of an instruction go in the byte that addresses them.
156///
157/// An index rather than the argument, for the reason [`Arg`] gives: the order an instruction is
158/// written in is not the order its operands are in, and an argument the machine needs may be one
159/// the assembler does not write.
160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
161pub enum Fields {
162    /// No addressing byte at all, which is an instruction whose arguments are all in the opcode
163    /// or are the distance to somewhere else.
164    None,
165    /// The argument at that index is addressed, and the three bits beside it in the byte are more
166    /// of the opcode rather than a second register. Eight instructions share `0xF7` this way.
167    Ext {
168        /// The argument the byte addresses, which is a register or an address.
169        rm: u8,
170        /// The three bits that finish the opcode.
171        ext: u8,
172    },
173    /// The argument at `rm` is addressed and the one at `reg` is the register beside it.
174    Pair {
175        /// The argument the byte addresses, which is a register or an address.
176        rm: u8,
177        /// The argument in the register field, which is always a register.
178        reg: u8,
179    },
180    /// The low three bits of that argument's register are added to the last byte of the opcode,
181    /// which is how a push, a pop and the ten byte move name theirs.
182    Plus {
183        /// The argument whose register is in the opcode.
184        reg: u8,
185    },
186}
187
188/// The immediate an instruction carries, behind everything else it is made of.
189///
190/// Named the way the manual names them, because this is a table a person checks against one.
191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192pub enum ImmSize {
193    /// None at all.
194    None,
195    /// One byte.
196    Ib,
197    /// Two bytes.
198    Iw,
199    /// Four bytes.
200    Id,
201    /// Eight bytes, which only the ten byte move has.
202    Io,
203    /// Four bytes of signed distance from the end of the instruction, which is what a jump and a
204    /// call carry and is filled in once the place it goes to is known.
205    Cd,
206}
207
208/// Which immediates a row is for.
209///
210/// Two jobs. It is how one instruction has more than one encoding, since the arithmetic
211/// instructions have a short form for a small number and the sixty four bit move has a long one
212/// for a big one. And it is how a number too big for any form of an instruction is refused rather
213/// than quietly cut down, which would be a compiler that writes a different program from the one
214/// it was given.
215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
216pub enum Fits {
217    /// Any at all, which is what a row with no immediate takes and what the one instruction with
218    /// an eight byte immediate takes.
219    Any,
220    /// One that fits in a signed byte, which is the short form every arithmetic instruction here
221    /// has and is why the general row is written behind it.
222    Signed8,
223    /// One that fits in four signed bytes, which is as far as an instruction that sign extends
224    /// what it carries reaches. That is the seven byte form of the sixty four bit move, and it is
225    /// also every sixty four bit arithmetic instruction with an immediate, because four bytes is
226    /// the widest immediate the machine has outside that one move.
227    Signed32,
228    /// One that fits in a byte, counted either way, since a number over a hundred and twenty
229    /// seven and the negative one it would be read as are the same eight bits.
230    Byte,
231    /// One that fits in two bytes, counted either way.
232    Word,
233    /// One that fits in four bytes, counted either way.
234    Long,
235}
236
237impl Fits {
238    /// Whether this row is one that number may be written with.
239    fn holds(self, imm: i64) -> bool {
240        match self {
241            Fits::Any => true,
242            Signed8 => i8::try_from(imm).is_ok(),
243            Signed32 => i32::try_from(imm).is_ok(),
244            Fits::Byte => i8::try_from(imm).is_ok() || u8::try_from(imm).is_ok(),
245            Fits::Word => i16::try_from(imm).is_ok() || u16::try_from(imm).is_ok(),
246            Fits::Long => i32::try_from(imm).is_ok() || u32::try_from(imm).is_ok(),
247        }
248    }
249}
250
251/// One instruction of the machine, as a processor reads it.
252#[derive(Debug, Clone, Copy, PartialEq, Eq)]
253pub struct Encoding {
254    /// The mnemonic, which is the one [`Written`](crate::x86_64::Written) carries.
255    pub mnemonic: &'static str,
256    /// What each of its arguments is, in the order they are written.
257    pub args: &'static [Kind],
258    /// Which immediates this row is for.
259    pub fits: Fits,
260    /// What the prefixes say the operands are.
261    pub size: Size,
262    /// The bytes of the opcode itself, in front of everything the arguments decide.
263    pub opcode: &'static [u8],
264    /// Where the arguments go in the byte that addresses them.
265    pub fields: Fields,
266    /// The immediate behind the rest of it.
267    pub imm: ImmSize,
268}
269
270/// One row of the table below, for an instruction that carries no immediate or that carries one
271/// of any size at all.
272const fn bytes(
273    mnemonic: &'static str,
274    args: &'static [Kind],
275    size: Size,
276    opcode: &'static [u8],
277    fields: Fields,
278    imm: ImmSize,
279) -> Encoding {
280    Encoding { mnemonic, args, fits: Fits::Any, size, opcode, fields, imm }
281}
282
283/// One row for an instruction whose immediate has to be of a certain size, which is every row
284/// here that carries one but the ten byte move.
285const fn takes(
286    mnemonic: &'static str,
287    args: &'static [Kind],
288    fits: Fits,
289    size: Size,
290    opcode: &'static [u8],
291    fields: Fields,
292    imm: ImmSize,
293) -> Encoding {
294    Encoding { mnemonic, args, fits, size, opcode, fields, imm }
295}
296
297/// An addressing byte whose spare three bits finish the opcode.
298const fn ext(rm: u8, ext: u8) -> Fields {
299    Fields::Ext { rm, ext }
300}
301
302/// An addressing byte that names two registers, or one register and an address.
303const fn pair(rm: u8, reg: u8) -> Fields {
304    Fields::Pair { rm, reg }
305}
306
307/// A register in the last byte of the opcode.
308const fn plus(reg: u8) -> Fields {
309    Fields::Plus { reg }
310}
311
312/// No addressing byte.
313const NO_MODRM: Fields = Fields::None;
314/// No immediate.
315const NO_IMM: ImmSize = ImmSize::None;
316
317// The argument lists, which are short and repeat, so they are written once and named. AT&T order
318// throughout, so the source is in front of the destination.
319static NO_ARGS: [Kind; 0] = [];
320static R: [Kind; 1] = [Kind::Reg];
321static RR: [Kind; 2] = [Kind::Reg, Kind::Reg];
322static IR: [Kind; 2] = [Kind::Imm, Kind::Reg];
323static IRR: [Kind; 3] = [Kind::Imm, Kind::Reg, Kind::Reg];
324static MR: [Kind; 2] = [Kind::Mem, Kind::Reg];
325static RM: [Kind; 2] = [Kind::Reg, Kind::Mem];
326static D: [Kind; 1] = [Kind::Dest];
327// The same shapes with a vector register in them, which is a different row rather than a different
328// spelling of the same one for the reason `Kind::Vec` gives.
329static VV: [Kind; 2] = [Kind::Vec, Kind::Vec];
330static MV: [Kind; 2] = [Kind::Mem, Kind::Vec];
331static VM: [Kind; 2] = [Kind::Vec, Kind::Mem];
332static RV: [Kind; 2] = [Kind::Reg, Kind::Vec];
333static VR: [Kind; 2] = [Kind::Vec, Kind::Reg];
334
335/// Every instruction [`crate::x86_64::written`] can name, and the bytes it comes out as.
336///
337/// In the order the opcodes that reach them are described in, and grouped the same way, so that
338/// a reader with the manual open can go down all three tables together. An instruction reached
339/// from more than one opcode is written once, where it is first reached, which is why the
340/// conversions hold the widening a division needs and the arithmetic holds the clearing.
341///
342/// A row for a small immediate comes in front of the general row for the same instruction,
343/// because a lookup takes the first row that fits and the narrower one is the one wanted.
344static ENCODINGS: &[Encoding] = &[
345    // Constants. The sixty four bit form is ten bytes with the number in it, and seven when four
346    // sign extended bytes reach it, which is nearly always.
347    takes("movb", &IR, Fits::Byte, Byte, &[0xC6], ext(1, 0), ImmSize::Ib),
348    takes("movw", &IR, Fits::Word, Word, &[0xC7], ext(1, 0), ImmSize::Iw),
349    takes("movl", &IR, Fits::Long, Long, &[0xC7], ext(1, 0), ImmSize::Id),
350    takes("movq", &IR, Signed32, Quad, &[0xC7], ext(1, 0), ImmSize::Id),
351    bytes("movq", &IR, Quad, &[0xB8], plus(1), ImmSize::Io),
352    // Arithmetic, register with register. The source is written first and is the register beside
353    // the addressing byte, and the destination is the one the byte addresses.
354    bytes("addb", &RR, Byte, &[0x00], pair(1, 0), NO_IMM),
355    bytes("addw", &RR, Word, &[0x01], pair(1, 0), NO_IMM),
356    bytes("addl", &RR, Long, &[0x01], pair(1, 0), NO_IMM),
357    bytes("addq", &RR, Quad, &[0x01], pair(1, 0), NO_IMM),
358    bytes("subb", &RR, Byte, &[0x28], pair(1, 0), NO_IMM),
359    bytes("subw", &RR, Word, &[0x29], pair(1, 0), NO_IMM),
360    bytes("subl", &RR, Long, &[0x29], pair(1, 0), NO_IMM),
361    bytes("subq", &RR, Quad, &[0x29], pair(1, 0), NO_IMM),
362    bytes("andb", &RR, Byte, &[0x20], pair(1, 0), NO_IMM),
363    bytes("andw", &RR, Word, &[0x21], pair(1, 0), NO_IMM),
364    bytes("andl", &RR, Long, &[0x21], pair(1, 0), NO_IMM),
365    bytes("andq", &RR, Quad, &[0x21], pair(1, 0), NO_IMM),
366    bytes("orb", &RR, Byte, &[0x08], pair(1, 0), NO_IMM),
367    bytes("orw", &RR, Word, &[0x09], pair(1, 0), NO_IMM),
368    bytes("orl", &RR, Long, &[0x09], pair(1, 0), NO_IMM),
369    bytes("orq", &RR, Quad, &[0x09], pair(1, 0), NO_IMM),
370    bytes("xorb", &RR, Byte, &[0x30], pair(1, 0), NO_IMM),
371    bytes("xorw", &RR, Word, &[0x31], pair(1, 0), NO_IMM),
372    bytes("xorl", &RR, Long, &[0x31], pair(1, 0), NO_IMM),
373    bytes("xorq", &RR, Quad, &[0x31], pair(1, 0), NO_IMM),
374    // The multiply is the other way round from the rest of them: it is not one of the eight that
375    // share an opcode column, and the register beside the addressing byte is its destination.
376    bytes("imulw", &RR, Word, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
377    bytes("imull", &RR, Long, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
378    bytes("imulq", &RR, Quad, &[0x0F, 0xAF], pair(0, 1), NO_IMM),
379    // Arithmetic, register with immediate. The eight of these share three opcodes and are told
380    // apart by the three bits beside the register, which is the column the manual calls `/digit`.
381    // Nothing narrower than a word can sign extend a byte, since a byte is already one.
382    takes("addb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 0), ImmSize::Ib),
383    takes("addw", &IR, Signed8, Word, &[0x83], ext(1, 0), ImmSize::Ib),
384    takes("addw", &IR, Fits::Word, Word, &[0x81], ext(1, 0), ImmSize::Iw),
385    takes("addl", &IR, Signed8, Long, &[0x83], ext(1, 0), ImmSize::Ib),
386    takes("addl", &IR, Fits::Long, Long, &[0x81], ext(1, 0), ImmSize::Id),
387    takes("addq", &IR, Signed8, Quad, &[0x83], ext(1, 0), ImmSize::Ib),
388    takes("addq", &IR, Signed32, Quad, &[0x81], ext(1, 0), ImmSize::Id),
389    takes("subb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 5), ImmSize::Ib),
390    takes("subw", &IR, Signed8, Word, &[0x83], ext(1, 5), ImmSize::Ib),
391    takes("subw", &IR, Fits::Word, Word, &[0x81], ext(1, 5), ImmSize::Iw),
392    takes("subl", &IR, Signed8, Long, &[0x83], ext(1, 5), ImmSize::Ib),
393    takes("subl", &IR, Fits::Long, Long, &[0x81], ext(1, 5), ImmSize::Id),
394    takes("subq", &IR, Signed8, Quad, &[0x83], ext(1, 5), ImmSize::Ib),
395    takes("subq", &IR, Signed32, Quad, &[0x81], ext(1, 5), ImmSize::Id),
396    takes("andb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 4), ImmSize::Ib),
397    takes("andw", &IR, Signed8, Word, &[0x83], ext(1, 4), ImmSize::Ib),
398    takes("andw", &IR, Fits::Word, Word, &[0x81], ext(1, 4), ImmSize::Iw),
399    takes("andl", &IR, Signed8, Long, &[0x83], ext(1, 4), ImmSize::Ib),
400    takes("andl", &IR, Fits::Long, Long, &[0x81], ext(1, 4), ImmSize::Id),
401    takes("andq", &IR, Signed8, Quad, &[0x83], ext(1, 4), ImmSize::Ib),
402    takes("andq", &IR, Signed32, Quad, &[0x81], ext(1, 4), ImmSize::Id),
403    takes("orb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 1), ImmSize::Ib),
404    takes("orw", &IR, Signed8, Word, &[0x83], ext(1, 1), ImmSize::Ib),
405    takes("orw", &IR, Fits::Word, Word, &[0x81], ext(1, 1), ImmSize::Iw),
406    takes("orl", &IR, Signed8, Long, &[0x83], ext(1, 1), ImmSize::Ib),
407    takes("orl", &IR, Fits::Long, Long, &[0x81], ext(1, 1), ImmSize::Id),
408    takes("orq", &IR, Signed8, Quad, &[0x83], ext(1, 1), ImmSize::Ib),
409    takes("orq", &IR, Signed32, Quad, &[0x81], ext(1, 1), ImmSize::Id),
410    takes("xorb", &IR, Fits::Byte, Byte, &[0x80], ext(1, 6), ImmSize::Ib),
411    takes("xorw", &IR, Signed8, Word, &[0x83], ext(1, 6), ImmSize::Ib),
412    takes("xorw", &IR, Fits::Word, Word, &[0x81], ext(1, 6), ImmSize::Iw),
413    takes("xorl", &IR, Signed8, Long, &[0x83], ext(1, 6), ImmSize::Ib),
414    takes("xorl", &IR, Fits::Long, Long, &[0x81], ext(1, 6), ImmSize::Id),
415    takes("xorq", &IR, Signed8, Quad, &[0x83], ext(1, 6), ImmSize::Ib),
416    takes("xorq", &IR, Signed32, Quad, &[0x81], ext(1, 6), ImmSize::Id),
417    // The three-operand multiply, whose source and destination are both written because they are
418    // not the same register and whose immediate narrows the same way the eight above do.
419    takes("imulw", &IRR, Signed8, Word, &[0x6B], pair(1, 2), ImmSize::Ib),
420    takes("imulw", &IRR, Fits::Word, Word, &[0x69], pair(1, 2), ImmSize::Iw),
421    takes("imull", &IRR, Signed8, Long, &[0x6B], pair(1, 2), ImmSize::Ib),
422    takes("imull", &IRR, Fits::Long, Long, &[0x69], pair(1, 2), ImmSize::Id),
423    takes("imulq", &IRR, Signed8, Quad, &[0x6B], pair(1, 2), ImmSize::Ib),
424    takes("imulq", &IRR, Signed32, Quad, &[0x69], pair(1, 2), ImmSize::Id),
425    // Negation and complement, which are two more of the eight that share `0xF7`.
426    bytes("negb", &R, Byte, &[0xF6], ext(0, 3), NO_IMM),
427    bytes("negw", &R, Word, &[0xF7], ext(0, 3), NO_IMM),
428    bytes("negl", &R, Long, &[0xF7], ext(0, 3), NO_IMM),
429    bytes("negq", &R, Quad, &[0xF7], ext(0, 3), NO_IMM),
430    bytes("notb", &R, Byte, &[0xF6], ext(0, 2), NO_IMM),
431    bytes("notw", &R, Word, &[0xF7], ext(0, 2), NO_IMM),
432    bytes("notl", &R, Long, &[0xF7], ext(0, 2), NO_IMM),
433    bytes("notq", &R, Quad, &[0xF7], ext(0, 2), NO_IMM),
434    // The four widenings a division needs, each of which is one byte and a prefix. They read one
435    // fixed register and write another and name neither, which is why they have no arguments.
436    bytes("cbtw", &NO_ARGS, Word, &[0x98], NO_MODRM, NO_IMM),
437    bytes("cwtd", &NO_ARGS, Word, &[0x99], NO_MODRM, NO_IMM),
438    bytes("cltd", &NO_ARGS, Long, &[0x99], NO_MODRM, NO_IMM),
439    bytes("cqto", &NO_ARGS, Quad, &[0x99], NO_MODRM, NO_IMM),
440    // The divisions themselves, which are the last two of the eight.
441    bytes("idivb", &R, Byte, &[0xF6], ext(0, 7), NO_IMM),
442    bytes("idivw", &R, Word, &[0xF7], ext(0, 7), NO_IMM),
443    bytes("idivl", &R, Long, &[0xF7], ext(0, 7), NO_IMM),
444    bytes("idivq", &R, Quad, &[0xF7], ext(0, 7), NO_IMM),
445    bytes("divb", &R, Byte, &[0xF6], ext(0, 6), NO_IMM),
446    bytes("divw", &R, Word, &[0xF7], ext(0, 6), NO_IMM),
447    bytes("divl", &R, Long, &[0xF7], ext(0, 6), NO_IMM),
448    bytes("divq", &R, Quad, &[0xF7], ext(0, 6), NO_IMM),
449    // Shifts by a constant, which carry one byte of count however wide the thing shifted is,
450    // because nothing shifts a register by more than sixty three places.
451    takes("shlb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 4), ImmSize::Ib),
452    takes("shlw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 4), ImmSize::Ib),
453    takes("shll", &IR, Fits::Byte, Long, &[0xC1], ext(1, 4), ImmSize::Ib),
454    takes("shlq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 4), ImmSize::Ib),
455    takes("shrb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 5), ImmSize::Ib),
456    takes("shrw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 5), ImmSize::Ib),
457    takes("shrl", &IR, Fits::Byte, Long, &[0xC1], ext(1, 5), ImmSize::Ib),
458    takes("shrq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 5), ImmSize::Ib),
459    takes("sarb", &IR, Fits::Byte, Byte, &[0xC0], ext(1, 7), ImmSize::Ib),
460    takes("sarw", &IR, Fits::Byte, Word, &[0xC1], ext(1, 7), ImmSize::Ib),
461    takes("sarl", &IR, Fits::Byte, Long, &[0xC1], ext(1, 7), ImmSize::Ib),
462    takes("sarq", &IR, Fits::Byte, Quad, &[0xC1], ext(1, 7), ImmSize::Ib),
463    // Shifts by a count, which is written and not encoded: the machine reads it from `cl` and
464    // there is nowhere in the instruction to say so. The count is the argument at zero, and every
465    // row here addresses the argument at one.
466    bytes("shlb", &RR, Byte, &[0xD2], ext(1, 4), NO_IMM),
467    bytes("shlw", &RR, Word, &[0xD3], ext(1, 4), NO_IMM),
468    bytes("shll", &RR, Long, &[0xD3], ext(1, 4), NO_IMM),
469    bytes("shlq", &RR, Quad, &[0xD3], ext(1, 4), NO_IMM),
470    bytes("shrb", &RR, Byte, &[0xD2], ext(1, 5), NO_IMM),
471    bytes("shrw", &RR, Word, &[0xD3], ext(1, 5), NO_IMM),
472    bytes("shrl", &RR, Long, &[0xD3], ext(1, 5), NO_IMM),
473    bytes("shrq", &RR, Quad, &[0xD3], ext(1, 5), NO_IMM),
474    bytes("sarb", &RR, Byte, &[0xD2], ext(1, 7), NO_IMM),
475    bytes("sarw", &RR, Word, &[0xD3], ext(1, 7), NO_IMM),
476    bytes("sarl", &RR, Long, &[0xD3], ext(1, 7), NO_IMM),
477    bytes("sarq", &RR, Quad, &[0xD3], ext(1, 7), NO_IMM),
478    // The comparison, which is the eighth of the ones that share an opcode column and is written
479    // the same way round as the subtraction it is.
480    bytes("cmpb", &RR, Byte, &[0x38], pair(1, 0), NO_IMM),
481    bytes("cmpw", &RR, Word, &[0x39], pair(1, 0), NO_IMM),
482    bytes("cmpl", &RR, Long, &[0x39], pair(1, 0), NO_IMM),
483    bytes("cmpq", &RR, Quad, &[0x39], pair(1, 0), NO_IMM),
484    // The byte each condition sets, which is one opcode with the condition in its low four bits.
485    bytes("sete", &R, Byte, &[0x0F, 0x94], ext(0, 0), NO_IMM),
486    bytes("setne", &R, Byte, &[0x0F, 0x95], ext(0, 0), NO_IMM),
487    bytes("setl", &R, Byte, &[0x0F, 0x9C], ext(0, 0), NO_IMM),
488    bytes("setle", &R, Byte, &[0x0F, 0x9E], ext(0, 0), NO_IMM),
489    bytes("setg", &R, Byte, &[0x0F, 0x9F], ext(0, 0), NO_IMM),
490    bytes("setge", &R, Byte, &[0x0F, 0x9D], ext(0, 0), NO_IMM),
491    bytes("setb", &R, Byte, &[0x0F, 0x92], ext(0, 0), NO_IMM),
492    bytes("setbe", &R, Byte, &[0x0F, 0x96], ext(0, 0), NO_IMM),
493    bytes("seta", &R, Byte, &[0x0F, 0x97], ext(0, 0), NO_IMM),
494    bytes("setae", &R, Byte, &[0x0F, 0x93], ext(0, 0), NO_IMM),
495    // The two conditions on the parity flag, which are here because a float comparison is the one
496    // thing on this machine that sets it for a reason anybody wants. It says the two operands were
497    // not ordered, which is to say one of them was a NaN.
498    bytes("setp", &R, Byte, &[0x0F, 0x9A], ext(0, 0), NO_IMM),
499    bytes("setnp", &R, Byte, &[0x0F, 0x9B], ext(0, 0), NO_IMM),
500    // The conversions between widths, which read a register and write a wider one, so the
501    // destination is the register beside the addressing byte rather than the one it addresses.
502    // How wide the source is decides the opcode and how wide the destination is decides the
503    // prefix, which is why five opcodes make eleven instructions.
504    bytes("movzbw", &RR, Word, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
505    bytes("movzbl", &RR, Long, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
506    bytes("movzbq", &RR, Quad, &[0x0F, 0xB6], pair(0, 1), NO_IMM),
507    bytes("movzwl", &RR, Long, &[0x0F, 0xB7], pair(0, 1), NO_IMM),
508    bytes("movzwq", &RR, Quad, &[0x0F, 0xB7], pair(0, 1), NO_IMM),
509    bytes("movsbw", &RR, Word, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
510    bytes("movsbl", &RR, Long, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
511    bytes("movsbq", &RR, Quad, &[0x0F, 0xBE], pair(0, 1), NO_IMM),
512    bytes("movswl", &RR, Long, &[0x0F, 0xBF], pair(0, 1), NO_IMM),
513    bytes("movswq", &RR, Quad, &[0x0F, 0xBF], pair(0, 1), NO_IMM),
514    bytes("movslq", &RR, Quad, &[0x63], pair(0, 1), NO_IMM),
515    // A copy between registers, which is a store to a register rather than a load from one, so it
516    // is written the same way round as the arithmetic above and not as the conversions.
517    bytes("movb", &RR, Byte, &[0x88], pair(1, 0), NO_IMM),
518    bytes("movw", &RR, Word, &[0x89], pair(1, 0), NO_IMM),
519    bytes("movl", &RR, Long, &[0x89], pair(1, 0), NO_IMM),
520    bytes("movq", &RR, Quad, &[0x89], pair(1, 0), NO_IMM),
521    // The address computation, which is the one instruction that is given an address and does not
522    // read it.
523    bytes("leaq", &MR, Quad, &[0x8D], pair(0, 1), NO_IMM),
524    // Reading and writing memory, which are one opcode apart and are the same instruction with
525    // the two ends swapped.
526    bytes("movb", &MR, Byte, &[0x8A], pair(0, 1), NO_IMM),
527    bytes("movw", &MR, Word, &[0x8B], pair(0, 1), NO_IMM),
528    bytes("movl", &MR, Long, &[0x8B], pair(0, 1), NO_IMM),
529    bytes("movq", &MR, Quad, &[0x8B], pair(0, 1), NO_IMM),
530    bytes("movb", &RM, Byte, &[0x88], pair(1, 0), NO_IMM),
531    bytes("movw", &RM, Word, &[0x89], pair(1, 0), NO_IMM),
532    bytes("movl", &RM, Long, &[0x89], pair(1, 0), NO_IMM),
533    bytes("movq", &RM, Quad, &[0x89], pair(1, 0), NO_IMM),
534    // A call, whose distance to the function it goes to is not known here.
535    bytes("call", &D, Long, &[0xE8], NO_MODRM, ImmSize::Cd),
536    // The same mnemonic through an address, which is a different row rather than a different
537    // mnemonic because a lookup here is by what the arguments are and not only by what the
538    // instruction is called. It is one of the eight that share `0xFF` and is told from the rest by
539    // the three bits beside the register. Sixty four bits without a prefix saying so, the way a
540    // jump and a push are, since there is no form of it that calls a thirty two bit address.
541    bytes("call", &R, Long, &[0xFF], ext(0, 2), NO_IMM),
542    // What a condition and the block layout come to. The test is a comparison against zero that
543    // names the same register twice, so both of its arguments are the one operand.
544    bytes("testb", &RR, Byte, &[0x84], pair(1, 0), NO_IMM),
545    bytes("je", &D, Long, &[0x0F, 0x84], NO_MODRM, ImmSize::Cd),
546    bytes("jne", &D, Long, &[0x0F, 0x85], NO_MODRM, ImmSize::Cd),
547    bytes("jmp", &D, Long, &[0xE9], NO_MODRM, ImmSize::Cd),
548    // What a prologue and an epilogue are made of. A push and a pop move eight bytes without
549    // being told to, so neither carries the prefix that would say so.
550    bytes("pushq", &R, Long, &[0x50], plus(0), NO_IMM),
551    bytes("popq", &R, Long, &[0x58], plus(0), NO_IMM),
552    bytes("ret", &NO_ARGS, Long, &[0xC3], NO_MODRM, NO_IMM),
553    // The vector moves, which are the same three shapes as the general purpose ones and are one
554    // opcode apart the same way.
555    bytes("movaps", &VV, Long, &[0x0F, 0x28], pair(0, 1), NO_IMM),
556    bytes("movaps", &MV, Long, &[0x0F, 0x28], pair(0, 1), NO_IMM),
557    bytes("movaps", &VM, Long, &[0x0F, 0x29], pair(1, 0), NO_IMM),
558    // A scalar move, which is the same pair of opcodes one lower and behind the prefix that says
559    // which format it is. The load is `0x10` and the store is `0x11`, the way `movaps` is `0x28`
560    // and `0x29`, and the destination is the register beside the addressing byte in both.
561    bytes("movss", &MV, Single, &[0x0F, 0x10], pair(0, 1), NO_IMM),
562    bytes("movsd", &MV, Double, &[0x0F, 0x10], pair(0, 1), NO_IMM),
563    bytes("movss", &VM, Single, &[0x0F, 0x11], pair(1, 0), NO_IMM),
564    bytes("movsd", &VM, Double, &[0x0F, 0x11], pair(1, 0), NO_IMM),
565    // Scalar arithmetic. The four opcodes are consecutive, which is worth reading as a group: add
566    // is `0x58`, multiply `0x59`, subtract `0x5C` and divide `0x5E`, and the `float` and the
567    // `double` of each are the same byte behind a different prefix. The destination is the
568    // register beside the addressing byte here, the opposite way round from the integer
569    // arithmetic, because these instructions read their addressed operand and write the other.
570    bytes("addss", &VV, Single, &[0x0F, 0x58], pair(0, 1), NO_IMM),
571    bytes("addsd", &VV, Double, &[0x0F, 0x58], pair(0, 1), NO_IMM),
572    bytes("mulss", &VV, Single, &[0x0F, 0x59], pair(0, 1), NO_IMM),
573    bytes("mulsd", &VV, Double, &[0x0F, 0x59], pair(0, 1), NO_IMM),
574    bytes("subss", &VV, Single, &[0x0F, 0x5C], pair(0, 1), NO_IMM),
575    bytes("subsd", &VV, Double, &[0x0F, 0x5C], pair(0, 1), NO_IMM),
576    bytes("divss", &VV, Single, &[0x0F, 0x5E], pair(0, 1), NO_IMM),
577    bytes("divsd", &VV, Double, &[0x0F, 0x5E], pair(0, 1), NO_IMM),
578    // One format to the other, which is one opcode with the prefix saying which way round it
579    // goes: behind `0xF3` it reads a `float` and writes a `double` and behind `0xF2` it does the
580    // opposite, because the prefix says what the instruction reads.
581    bytes("cvtss2sd", &VV, Single, &[0x0F, 0x5A], pair(0, 1), NO_IMM),
582    bytes("cvtsd2ss", &VV, Double, &[0x0F, 0x5A], pair(0, 1), NO_IMM),
583    // A float to an integer, cutting towards zero, which is the rounding C asks for and is why
584    // the mnemonic has two `t`s in it: `cvtss2si` is the one that rounds and no C conversion
585    // wants it. The prefix says which format is read and `REX.W` says how wide the integer
586    // written is, which is the pair of questions the four rows are the four answers to. The
587    // suffix on the mnemonic is what tells two of these rows apart, since a row is found by what
588    // its arguments are and both widths of the answer are a general purpose register.
589    bytes("cvttss2sil", &VR, Single, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
590    bytes("cvttss2siq", &VR, SingleQuad, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
591    bytes("cvttsd2sil", &VR, Double, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
592    bytes("cvttsd2siq", &VR, DoubleQuad, &[0x0F, 0x2C], pair(0, 1), NO_IMM),
593    // An integer to a float, which is the same two questions the other way round and one opcode
594    // lower. The mnemonic carries the width of the integer here because the register it reads is
595    // the one the assembler cannot see in a memory form, and this table writes the suffix on
596    // every one of them so that the four read as four rather than as two written twice.
597    bytes("cvtsi2ssl", &RV, Single, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
598    bytes("cvtsi2ssq", &RV, SingleQuad, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
599    bytes("cvtsi2sdl", &RV, Double, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
600    bytes("cvtsi2sdq", &RV, DoubleQuad, &[0x0F, 0x2A], pair(0, 1), NO_IMM),
601    // The same bits moved from one file to the other, which is what a reinterpretation is. Two
602    // opcodes, `0x6E` towards the vector register and `0x7E` away from it, and the mnemonic is
603    // the width rather than the direction because the direction is which argument is which.
604    bytes("movd", &RV, Word, &[0x0F, 0x6E], pair(0, 1), NO_IMM),
605    bytes("movq", &RV, WordQuad, &[0x0F, 0x6E], pair(0, 1), NO_IMM),
606    bytes("movd", &VR, Word, &[0x0F, 0x7E], pair(1, 0), NO_IMM),
607    bytes("movq", &VR, WordQuad, &[0x0F, 0x7E], pair(1, 0), NO_IMM),
608    // Comparing two floats and setting the flags, which is one opcode with the prefix saying which
609    // format is read: no prefix for a `float` and `0x66` for a `double`, which is the pairing the
610    // moves at the top of this group have and not the one the arithmetic has. The register beside
611    // the addressing byte is the left hand side, so the comparison reads the same way round as
612    // `cvtss2sd` and the opposite way round from `cmpl`.
613    bytes("ucomiss", &VV, Long, &[0x0F, 0x2E], pair(0, 1), NO_IMM),
614    bytes("ucomisd", &VV, Word, &[0x0F, 0x2E], pair(0, 1), NO_IMM),
615];
616
617/// The encoding of the instruction of that mnemonic, given those arguments and that immediate.
618///
619/// `None` for a mnemonic this target does not encode, for one it does encode with arguments that
620/// are not the ones it takes, and for an immediate no form of it can carry.
621///
622/// The immediate is asked for because it is part of which instruction this is: two families here
623/// have a shorter encoding for a small number, and every one of them has a largest number it can
624/// hold. Pass zero for an instruction that carries none, which is what the first row of every
625/// such mnemonic accepts anyway.
626#[must_use]
627pub fn encoding(mnemonic: &str, args: &[Kind], imm: i64) -> Option<&'static Encoding> {
628    rows(mnemonic, args).find(|row| row.fits.holds(imm))
629}
630
631/// Every row of that mnemonic with those arguments, in the order they are written.
632fn rows<'a>(mnemonic: &'a str, args: &'a [Kind]) -> impl Iterator<Item = &'static Encoding> + 'a {
633    ENCODINGS.iter().filter(move |row| row.mnemonic == mnemonic && row.args == args)
634}
635
636/// An address, with everything about it already decided.
637///
638/// The machine IR's addressing mode names its registers by where they are in the operand vector
639/// and this names them outright, because by here the allocator has run and there is an answer.
640#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
641pub struct Addr {
642    /// The register the address starts from, if there is one.
643    pub base: Option<PhysReg>,
644    /// The register added to it, if there is one. It may not be the stack pointer, which is the
645    /// number the encoding uses to say there is no index at all.
646    pub index: Option<PhysReg>,
647    /// What the index is multiplied by, which is one, two, four or eight. Ignored when there is
648    /// no index.
649    pub scale: u8,
650    /// The constant added to the rest of it.
651    pub disp: i32,
652    /// Whether the address is counted from the end of the instruction rather than from a
653    /// register, which is how a global is reached in position independent code and is the only
654    /// way this compiler reaches one. It names no register, so it has neither base nor index.
655    pub rip: bool,
656}
657
658/// What one argument of an instruction turned out to be.
659#[derive(Debug, Clone, Copy, PartialEq, Eq)]
660pub enum Value {
661    /// A register, and how much of it the instruction reads or writes.
662    ///
663    /// The width is here because it is what decides whether a REX byte is needed at all: the four
664    /// registers numbered four to seven are `ah`, `ch`, `dh` and `bh` as bytes without one and
665    /// `spl`, `bpl`, `sil` and `dil` with one, so a byte instruction naming one of the second set
666    /// carries a REX byte that says nothing else.
667    Reg(PhysReg, Width),
668    /// A vector register, all of which every instruction here that names one reads or writes.
669    ///
670    /// [`Value::Reg`] in the other file, and separate for the reason [`Kind::Vec`] gives. There is
671    /// no width, because there is nothing narrower than the whole of one to name: an instruction
672    /// that works on the low four bytes of a vector register is a different opcode rather than the
673    /// same opcode at another width, which is what `movss` and `movsd` are.
674    Xmm(PhysReg),
675    /// The byte above the low byte of one of the first four registers, which on this machine is
676    /// only ever `ah`.
677    ///
678    /// It is numbered like `spl` and told apart from it by the instruction having no REX byte,
679    /// which is why an instruction with one of these may name no register that needs one.
680    High(PhysReg),
681    /// An address.
682    Mem(Addr),
683    /// The number an immediate carries.
684    Imm(i64),
685    /// Somewhere else in the program, whose distance from here is not known yet.
686    Dest,
687}
688
689impl Value {
690    /// What kind of argument this is, which is half of what picks an encoding.
691    #[must_use]
692    pub fn kind(self) -> Kind {
693        match self {
694            Value::Reg(_, _) | Value::High(_) => Kind::Reg,
695            Value::Xmm(_) => Kind::Vec,
696            Value::Mem(_) => Kind::Mem,
697            Value::Imm(_) => Kind::Imm,
698            Value::Dest => Kind::Dest,
699        }
700    }
701}
702
703/// Where in an instruction something the encoder could not know goes.
704///
705/// Both are offsets into the buffer the instruction was written to rather than into the
706/// instruction, since what the caller has to do with either is patch the buffer or record a
707/// relocation against it.
708#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
709pub struct Holes {
710    /// Where the four bytes a jump or a call leaves for the distance to its target begin.
711    pub dest: Option<usize>,
712    /// Where the four bytes an address counted from the end of the instruction leaves for its
713    /// displacement begin.
714    pub rip: Option<usize>,
715}
716
717/// Why an instruction could not be encoded.
718///
719/// Every one of these is a bug in the compiler rather than anything a program could ask for, so
720/// they carry enough to say which instruction it was and nothing more.
721#[derive(Debug, Clone, PartialEq, Eq)]
722pub enum Error {
723    /// Nothing here encodes that mnemonic with those arguments.
724    Unwritten {
725        /// The mnemonic that was asked for.
726        mnemonic: String,
727        /// What its arguments were.
728        args: Vec<Kind>,
729    },
730    /// An immediate no form of that instruction can carry, which the machine cannot write and
731    /// which would be a different number if it were cut down to fit.
732    Immediate {
733        /// The mnemonic that was asked for.
734        mnemonic: String,
735        /// The number that would not fit.
736        imm: i64,
737    },
738    /// An instruction naming `ah` and also a register that cannot be named without a REX byte,
739    /// which is a pair the encoding has no way to write.
740    Crowded {
741        /// The mnemonic that was asked for.
742        mnemonic: String,
743    },
744    /// A scale that is not one of the four the machine has.
745    Scale {
746        /// What was asked for.
747        scale: u8,
748    },
749    /// The stack pointer as an index, which is the one register that cannot be one, because its
750    /// number is what the encoding uses to say there is no index.
751    Index,
752    /// An argument that is not the kind the row said it was, which cannot happen through
753    /// [`encode`] and can through a row that disagrees with itself.
754    Argument {
755        /// The mnemonic that was asked for.
756        mnemonic: String,
757        /// Which argument it was.
758        at: u8,
759    },
760}
761
762impl fmt::Display for Error {
763    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
764        match self {
765            Error::Unwritten { mnemonic, args } => {
766                write!(f, "no encoding for {mnemonic} with {} arguments {args:?}", args.len())
767            }
768            Error::Immediate { mnemonic, imm } => {
769                write!(f, "no form of {mnemonic} can carry the immediate {imm}")
770            }
771            Error::Crowded { mnemonic } => {
772                write!(f, "{mnemonic} names ah and a register that needs a rex byte")
773            }
774            Error::Scale { scale } => write!(f, "{scale} is not a scale this machine has"),
775            Error::Index => write!(f, "the stack pointer cannot be an index"),
776            Error::Argument { mnemonic, at } => {
777                write!(f, "argument {at} of {mnemonic} is not what its encoding expects")
778            }
779        }
780    }
781}
782
783impl std::error::Error for Error {}
784
785/// The bit of a REX byte that says the operands are sixty four bits.
786const REX_W: u8 = 0b1000;
787/// The bit that carries the top of the register beside the addressing byte.
788const REX_R: u8 = 0b0100;
789/// The bit that carries the top of an index register.
790const REX_X: u8 = 0b0010;
791/// The bit that carries the top of the register the addressing byte addresses, which is also the
792/// top of a base register and of a register in the opcode.
793const REX_B: u8 = 0b0001;
794
795/// Writes one instruction of the machine onto the end of `out`.
796///
797/// The values are the arguments in the order they are written, which is the order
798/// [`Written::args`](crate::x86_64::Written::args) holds them in, so a caller resolves each of
799/// those and hands the results here.
800///
801/// # Errors
802///
803/// [`Error::Unwritten`] for an instruction this does not encode, and the rest for an instruction
804/// it does encode that was handed something the machine cannot express. All of them are bugs
805/// rather than anything a program could ask for. See [`Error`].
806pub fn encode(mnemonic: &str, values: &[Value], out: &mut Vec<u8>) -> Result<Holes, Error> {
807    let args: Vec<Kind> = values.iter().map(|value| value.kind()).collect();
808    let imm = values
809        .iter()
810        .find_map(|value| match value {
811            Value::Imm(number) => Some(*number),
812            _ => None,
813        })
814        .unwrap_or(0);
815    let Some(row) = encoding(mnemonic, &args, imm) else {
816        // Which of the two it is says something different to whoever reads it. An instruction
817        // with no row at all is a hole in this description, and one whose rows are all too narrow
818        // is a lowering that produced a constant the instruction it chose cannot hold.
819        return Err(if rows(mnemonic, &args).next().is_some() {
820            Error::Immediate { mnemonic: mnemonic.to_owned(), imm }
821        } else {
822            Error::Unwritten { mnemonic: mnemonic.to_owned(), args }
823        });
824    };
825    Writer { row, values, rex: 0, forced: false, banned: false }.write(out, imm)
826}
827
828/// One instruction being written out.
829struct Writer<'a> {
830    row: &'a Encoding,
831    values: &'a [Value],
832    /// The low four bits of the REX byte, which are the tops of the register numbers.
833    rex: u8,
834    /// Whether a REX byte has to be written even when it would say nothing, which is what naming
835    /// one of the four registers that are only bytes with one asks for.
836    forced: bool,
837    /// Whether one may not be written at all, which is what naming `ah` asks for.
838    banned: bool,
839}
840
841impl Writer<'_> {
842    /// The whole instruction: what the arguments come to, then the bytes in the order they go in.
843    ///
844    /// The addressing byte and everything behind it are worked out before anything is written,
845    /// because they are what says whether there is a REX byte and the REX byte goes in front.
846    fn write(mut self, out: &mut Vec<u8>, imm: i64) -> Result<Holes, Error> {
847        let mut tail = Vec::new();
848        let mut holes = Holes::default();
849        let mut plus = 0;
850        match self.row.fields {
851            Fields::None => {}
852            Fields::Ext { rm, ext } => self.address(rm, ext, &mut tail, &mut holes)?,
853            Fields::Pair { rm, reg } => {
854                let reg = self.number(reg, REX_R)?;
855                self.address(rm, reg, &mut tail, &mut holes)?;
856            }
857            Fields::Plus { reg } => plus = self.number(reg, REX_B)?,
858        }
859        if self.banned && (self.forced || self.rex != 0) {
860            return Err(Error::Crowded { mnemonic: self.row.mnemonic.to_owned() });
861        }
862
863        if let Some(prefix) = self.row.size.prefix() {
864            out.push(prefix);
865        }
866        let rex = if self.row.size.wide() { self.rex | REX_W } else { self.rex };
867        if rex != 0 || (self.forced && !self.banned) {
868            out.push(0x40 | rex);
869        }
870        let (last, front) = self.row.opcode.split_last().expect("an opcode is at least one byte");
871        out.extend_from_slice(front);
872        out.push(last + plus);
873        // The offsets were taken against an empty buffer, so they move by however much is in
874        // front of the addressing byte by the time it is really written.
875        let at = out.len();
876        for hole in [&mut holes.dest, &mut holes.rip].into_iter().flatten() {
877            *hole += at;
878        }
879        out.extend_from_slice(&tail);
880
881        match self.row.imm {
882            ImmSize::None => {}
883            ImmSize::Ib => out.push(imm as u8),
884            ImmSize::Iw => out.extend_from_slice(&(imm as u16).to_le_bytes()),
885            ImmSize::Id => out.extend_from_slice(&(imm as u32).to_le_bytes()),
886            ImmSize::Io => out.extend_from_slice(&imm.to_le_bytes()),
887            ImmSize::Cd => {
888                holes.dest = Some(out.len());
889                out.extend_from_slice(&0i32.to_le_bytes());
890            }
891        }
892        Ok(holes)
893    }
894
895    /// The number of the register at that index, with its top bit put in the REX byte.
896    fn number(&mut self, at: u8, bit: u8) -> Result<u8, Error> {
897        match self.values.get(usize::from(at)) {
898            Some(&Value::Reg(reg, width)) => {
899                let number = reg.number();
900                if number >= 8 {
901                    self.rex |= bit;
902                }
903                // The one thing a width decides about the bytes. Every other difference between
904                // an eight, a sixteen, a thirty two and a sixty four bit instruction is in the
905                // opcode or in the prefixes, and those are on the row.
906                if width == Width::Byte && (4..8).contains(&number) {
907                    self.forced = true;
908                }
909                Ok(number & 7)
910            }
911            // A vector register is numbered the way a general purpose one is and there is no
912            // width to look at, since the whole of it is what the instruction works on.
913            Some(&Value::Xmm(reg)) => {
914                let number = reg.number();
915                if number >= 8 {
916                    self.rex |= bit;
917                }
918                Ok(number & 7)
919            }
920            // `ah` is `al` plus four, and so are the other three, which is also why only the
921            // first four registers have one.
922            Some(&Value::High(reg)) if reg.number() < 4 => {
923                self.banned = true;
924                Ok(reg.number() + 4)
925            }
926            _ => Err(Error::Argument { mnemonic: self.row.mnemonic.to_owned(), at }),
927        }
928    }
929
930    /// The addressing byte and whatever follows it, which is a register or a whole address.
931    ///
932    /// `reg` is the three bits beside the addressed one, which is either a register that has
933    /// already been worked out or the rest of the opcode.
934    fn address(
935        &mut self,
936        at: u8,
937        reg: u8,
938        out: &mut Vec<u8>,
939        holes: &mut Holes,
940    ) -> Result<(), Error> {
941        match self.values.get(usize::from(at)) {
942            Some(Value::Mem(addr)) => self.mem(*addr, reg, out, holes),
943            Some(_) => {
944                let rm = self.number(at, REX_B)?;
945                out.push(0b1100_0000 | (reg << 3) | rm);
946                Ok(())
947            }
948            None => Err(Error::Argument { mnemonic: self.row.mnemonic.to_owned(), at }),
949        }
950    }
951
952    /// One address, as the addressing byte and the two things that can follow it.
953    fn mem(
954        &mut self,
955        addr: Addr,
956        reg: u8,
957        out: &mut Vec<u8>,
958        holes: &mut Holes,
959    ) -> Result<(), Error> {
960        // Counted from the end of the instruction, which is the one mode with no register in it
961        // and is said by naming the base the encoding would otherwise use for no base at all.
962        if addr.rip {
963            out.push((reg << 3) | 0b101);
964            holes.rip = Some(out.len());
965            out.extend_from_slice(&addr.disp.to_le_bytes());
966            return Ok(());
967        }
968
969        let index = match addr.index {
970            Some(index) if index.number() == 4 => return Err(Error::Index),
971            Some(index) => {
972                if index.number() >= 8 {
973                    self.rex |= REX_X;
974                }
975                Some(index.number() & 7)
976            }
977            None => None,
978        };
979        let scale = match addr.scale {
980            _ if index.is_none() => 0,
981            1 => 0,
982            2 => 1,
983            4 => 2,
984            8 => 3,
985            scale => return Err(Error::Scale { scale }),
986        };
987        let base = addr.base.map(|base| {
988            if base.number() >= 8 {
989                self.rex |= REX_B;
990            }
991            base.number() & 7
992        });
993
994        // The stack pointer's number in the addressed field means there is a second byte instead
995        // of a register, so an address whose base really is the stack pointer needs that byte
996        // even when it has no index. The frame pointer's number with no displacement means the
997        // address is counted from the end of the instruction, so an address based on it always
998        // carries a displacement, and a byte of zero is the cheapest one.
999        let second = index.is_some() || base == Some(4) || base.is_none();
1000        let mode = match base {
1001            None => 0,
1002            Some(base) => {
1003                if addr.disp == 0 && base != 5 {
1004                    0
1005                } else if i8::try_from(addr.disp).is_ok() {
1006                    1
1007                } else {
1008                    2
1009                }
1010            }
1011        };
1012        out.push((mode << 6) | (reg << 3) | if second { 0b100 } else { base.unwrap_or(0) });
1013        if second {
1014            // Four in the index field is no index, and five in the base field with a mode of zero
1015            // is no base, which is how an address that is nothing but a number is written.
1016            out.push((scale << 6) | (index.unwrap_or(4) << 3) | base.unwrap_or(5));
1017        }
1018        match mode {
1019            0 if base.is_none() => out.extend_from_slice(&addr.disp.to_le_bytes()),
1020            0 => {}
1021            1 => out.push(addr.disp as u8),
1022            _ => out.extend_from_slice(&addr.disp.to_le_bytes()),
1023        }
1024        Ok(())
1025    }
1026}
1027
1028#[cfg(test)]
1029mod tests {
1030    use super::*;
1031    use crate::x86_64::text::written;
1032    use crate::x86_64::{INSTS, R8, R12, R13, RAX, RBP, RCX, RDX, RSI, RSP};
1033
1034    /// The bytes of that instruction, as a string a person can compare with a disassembler's.
1035    fn hex(mnemonic: &str, values: &[Value]) -> String {
1036        let mut out = Vec::new();
1037        encode(mnemonic, values, &mut out).expect("an instruction this target encodes");
1038        out.iter().map(|byte| format!("{byte:02x}")).collect::<Vec<_>>().join(" ")
1039    }
1040
1041    /// A whole register, which is what most arguments are.
1042    fn quad(reg: PhysReg) -> Value {
1043        Value::Reg(reg, Width::Quad)
1044    }
1045
1046    /// Thirty two bits of one.
1047    fn long(reg: PhysReg) -> Value {
1048        Value::Reg(reg, Width::Long)
1049    }
1050
1051    /// Eight bits of one.
1052    fn byte(reg: PhysReg) -> Value {
1053        Value::Reg(reg, Width::Byte)
1054    }
1055
1056    #[test]
1057    fn every_instruction_the_listing_writes_is_one_this_encodes() {
1058        // The claim `spec/11-asm-objects-debug.md` section 11.1 makes about the two paths sharing
1059        // a description. An instruction the text path writes and this cannot encode would be an
1060        // opcode that compiles under `-S` and fails to produce an object file.
1061        for &(opcode, _) in INSTS {
1062            let insts = written(opcode).expect("every described opcode is a written opcode");
1063            for inst in insts {
1064                let args: Vec<Kind> = inst.args.iter().map(|&arg| Kind::of(arg)).collect();
1065                assert!(
1066                    encoding(inst.mnemonic, &args, 0).is_some(),
1067                    "{opcode} writes {} with {args:?} and nothing encodes it",
1068                    inst.mnemonic
1069                );
1070            }
1071        }
1072    }
1073
1074    /// Numbers on both sides of every boundary any row here has.
1075    const PROBES: [i64; 11] =
1076        [0, 1, -1, 127, 128, -128, -129, 0xffff, 0x1_0000, 0x7fff_ffff, 0x1_0000_0000];
1077
1078    #[test]
1079    fn the_rows_of_one_instruction_go_from_the_smallest_immediate_to_the_largest() {
1080        // A lookup takes the first row that fits, so the order is the whole of what makes the
1081        // short forms reachable. A general row in front of a short one would leave the short one
1082        // dead, which nothing that encodes a single instruction would ever notice, and a row that
1083        // held nothing the one in front of it did not would be dead outright.
1084        for (at, row) in ENCODINGS.iter().enumerate() {
1085            for other in &ENCODINGS[at + 1..] {
1086                if other.mnemonic != row.mnemonic || other.args != row.args {
1087                    continue;
1088                }
1089                for imm in PROBES {
1090                    assert!(
1091                        !row.fits.holds(imm) || other.fits.holds(imm),
1092                        "{} takes {imm} in front of a row that does not",
1093                        row.mnemonic
1094                    );
1095                }
1096                assert!(
1097                    PROBES.iter().any(|&imm| other.fits.holds(imm) && !row.fits.holds(imm)),
1098                    "{} has a row behind another that holds no more than it",
1099                    row.mnemonic
1100                );
1101            }
1102        }
1103    }
1104
1105    #[test]
1106    fn an_immediate_no_form_of_an_instruction_can_hold_is_refused_rather_than_cut_down() {
1107        // The bug this is here for writes a program that adds a different number from the one it
1108        // was given, which nothing downstream could notice and no test of the text path could
1109        // either, since the text path writes the number out in full.
1110        let mut out = Vec::new();
1111        let big = 0x1_2345_6789;
1112        let error = encode("addq", &[Value::Imm(big), quad(RAX)], &mut out)
1113            .expect_err("more than four bytes of immediate");
1114        assert_eq!(error, Error::Immediate { mnemonic: "addq".to_owned(), imm: big });
1115        assert_eq!(out, Vec::<u8>::new());
1116        // The sixty four bit move is the one instruction that can hold it.
1117        assert!(encode("movq", &[Value::Imm(big), quad(RAX)], &mut out).is_ok());
1118        // And an immediate that fits either way round is one the machine can hold, since what it
1119        // carries is that many bits and not that many values.
1120        assert_eq!(hex("movl", &[Value::Imm(0xffff_ffff), long(RAX)]), "c7 c0 ff ff ff ff");
1121        assert_eq!(hex("addb", &[Value::Imm(200), byte(RAX)]), "80 c0 c8");
1122        assert_eq!(hex("shlq", &[Value::Imm(63), quad(RAX)]), "48 c1 e0 3f");
1123    }
1124
1125    #[test]
1126    fn an_instruction_with_two_registers_is_the_opcode_and_one_byte_that_names_both() {
1127        // The direction that is easy to get backwards. AT&T writes the source first and the byte
1128        // that names the two puts the destination in the half the manual calls `r/m`.
1129        assert_eq!(hex("addl", &[long(RCX), long(RAX)]), "01 c8");
1130        assert_eq!(hex("addl", &[long(RAX), long(RCX)]), "01 c1");
1131        // Sixty four bits is the same instruction with a byte in front saying so.
1132        assert_eq!(hex("addq", &[quad(RCX), quad(RAX)]), "48 01 c8");
1133        // Sixteen is the same instruction with a different byte in front.
1134        let word = [Value::Reg(RCX, Width::Word), Value::Reg(RAX, Width::Word)];
1135        assert_eq!(hex("addw", &word), "66 01 c8");
1136        // And a multiply is the other way round, because it is not one of the eight that share
1137        // an opcode column.
1138        assert_eq!(hex("imull", &[long(RCX), long(RAX)]), "0f af c1");
1139    }
1140
1141    #[test]
1142    fn a_register_the_second_half_of_the_machine_added_is_named_in_the_byte_in_front() {
1143        assert_eq!(hex("addl", &[long(R8), long(RAX)]), "44 01 c0");
1144        assert_eq!(hex("addl", &[long(RAX), long(R8)]), "41 01 c0");
1145        assert_eq!(hex("addq", &[quad(R8), quad(R8)]), "4d 01 c0");
1146        assert_eq!(hex("pushq", &[quad(R12)]), "41 54");
1147        assert_eq!(hex("popq", &[quad(RAX)]), "58");
1148    }
1149
1150    #[test]
1151    fn a_byte_register_the_machine_could_not_reach_before_forces_a_byte_that_says_nothing_else() {
1152        // Without the `40` these are `%dh` and `%bh`, which is the encoding bug that produces a
1153        // program reading a register nothing was ever put in.
1154        assert_eq!(hex("movb", &[byte(RSI), byte(RAX)]), "40 88 f0");
1155        assert_eq!(hex("sete", &[byte(RSI)]), "40 0f 94 c6");
1156        assert_eq!(hex("sete", &[byte(RAX)]), "0f 94 c0");
1157        // And the one instruction that names the high byte, which may have no such byte at all.
1158        assert_eq!(hex("movb", &[Value::High(RAX), byte(RDX)]), "88 e2");
1159        let mut out = Vec::new();
1160        let error = encode("movb", &[Value::High(RAX), byte(RSI)], &mut out)
1161            .expect_err("ah and sil in one instruction");
1162        assert_eq!(error, Error::Crowded { mnemonic: "movb".to_owned() });
1163    }
1164
1165    #[test]
1166    fn an_immediate_is_written_in_as_few_bytes_as_it_fits_in() {
1167        assert_eq!(hex("addl", &[Value::Imm(1), long(RCX)]), "83 c1 01");
1168        assert_eq!(hex("addl", &[Value::Imm(-1), long(RCX)]), "83 c1 ff");
1169        assert_eq!(hex("addl", &[Value::Imm(1000), long(RCX)]), "81 c1 e8 03 00 00");
1170        assert_eq!(hex("addq", &[Value::Imm(8), quad(RSP)]), "48 83 c4 08");
1171        // The move is the one instruction with an eight byte immediate, and it is ten bytes long
1172        // when it needs one and seven when it does not.
1173        assert_eq!(hex("movq", &[Value::Imm(1), quad(RAX)]), "48 c7 c0 01 00 00 00");
1174        assert_eq!(
1175            hex("movq", &[Value::Imm(0x1_2345_6789), quad(RAX)]),
1176            "48 b8 89 67 45 23 01 00 00 00"
1177        );
1178        // A thirty two bit move of a constant is never the ten byte form, because there is no
1179        // thirty two bit register that could hold a number too big for four bytes.
1180        assert_eq!(hex("movl", &[Value::Imm(1), long(RAX)]), "c7 c0 01 00 00 00");
1181    }
1182
1183    #[test]
1184    fn an_address_is_the_registers_it_names_and_whatever_is_added_to_them() {
1185        // A base on its own, which is the shortest.
1186        let base = Addr { base: Some(RCX), ..Addr::default() };
1187        assert_eq!(hex("movq", &[Value::Mem(base), quad(RAX)]), "48 8b 01");
1188        // A base and a displacement, in one byte where it fits and four where it does not.
1189        let near = Addr { base: Some(RCX), disp: -16, ..Addr::default() };
1190        assert_eq!(hex("movq", &[Value::Mem(near), quad(RAX)]), "48 8b 41 f0");
1191        let far = Addr { base: Some(RCX), disp: 1000, ..Addr::default() };
1192        assert_eq!(hex("movq", &[Value::Mem(far), quad(RAX)]), "48 8b 81 e8 03 00 00");
1193        // A base, an index and a scale, which needs the second byte.
1194        let indexed = Addr { base: Some(RCX), index: Some(RDX), scale: 4, disp: -16, rip: false };
1195        assert_eq!(hex("leaq", &[Value::Mem(indexed), quad(RAX)]), "48 8d 44 91 f0");
1196        // A store is the same address with the two ends the other way round.
1197        assert_eq!(hex("movl", &[long(RAX), Value::Mem(near)]), "89 41 f0");
1198    }
1199
1200    #[test]
1201    fn the_two_registers_an_address_cannot_be_written_with_plainly_are_written_around() {
1202        // The stack pointer's number means there is a second byte rather than a register, so an
1203        // address really based on it needs that byte even with nothing to put in it.
1204        let stack = Addr { base: Some(RSP), disp: 8, ..Addr::default() };
1205        assert_eq!(hex("movq", &[Value::Mem(stack), quad(RAX)]), "48 8b 44 24 08");
1206        // And the frame pointer's number with no displacement means the address is counted from
1207        // the end of the instruction, so one based on it always carries one.
1208        let frame = Addr { base: Some(RBP), ..Addr::default() };
1209        assert_eq!(hex("movq", &[Value::Mem(frame), quad(RAX)]), "48 8b 45 00");
1210        // The same two facts hold of the registers whose low three bits are theirs.
1211        let twelve = Addr { base: Some(R12), disp: 8, ..Addr::default() };
1212        assert_eq!(hex("movq", &[Value::Mem(twelve), quad(RAX)]), "49 8b 44 24 08");
1213        let thirteen = Addr { base: Some(R13), ..Addr::default() };
1214        assert_eq!(hex("movq", &[Value::Mem(thirteen), quad(RAX)]), "49 8b 45 00");
1215        // The stack pointer is the one register that cannot be an index at all.
1216        let mut out = Vec::new();
1217        let bad = Addr { base: Some(RCX), index: Some(RSP), scale: 1, disp: 0, rip: false };
1218        let error = encode("leaq", &[Value::Mem(bad), quad(RAX)], &mut out)
1219            .expect_err("the stack pointer as an index");
1220        assert_eq!(error, Error::Index);
1221    }
1222
1223    #[test]
1224    fn an_address_counted_from_the_end_of_the_instruction_leaves_its_displacement_open() {
1225        let global = Addr { rip: true, ..Addr::default() };
1226        let mut out = vec![0xcc];
1227        let holes = encode("movq", &[Value::Mem(global), quad(RAX)], &mut out).expect("a global");
1228        assert_eq!(out, [0xcc, 0x48, 0x8b, 0x05, 0, 0, 0, 0]);
1229        // Where the four bytes are, counted in the buffer rather than in the instruction, because
1230        // what the caller does with it is record a relocation against the buffer.
1231        assert_eq!(holes.rip, Some(4));
1232        assert_eq!(holes.dest, None);
1233    }
1234
1235    #[test]
1236    fn a_jump_leaves_the_distance_to_where_it_goes_open() {
1237        let mut out = Vec::new();
1238        let holes = encode("jmp", &[Value::Dest], &mut out).expect("a jump");
1239        assert_eq!(out, [0xe9, 0, 0, 0, 0]);
1240        assert_eq!(holes.dest, Some(1));
1241        out.clear();
1242        let holes = encode("je", &[Value::Dest], &mut out).expect("a conditional jump");
1243        assert_eq!(out, [0x0f, 0x84, 0, 0, 0, 0]);
1244        assert_eq!(holes.dest, Some(2));
1245    }
1246
1247    #[test]
1248    fn an_instruction_with_no_arguments_is_the_opcode_and_whatever_says_how_wide_it_is() {
1249        assert_eq!(hex("ret", &[]), "c3");
1250        assert_eq!(hex("cltd", &[]), "99");
1251        assert_eq!(hex("cqto", &[]), "48 99");
1252        assert_eq!(hex("cwtd", &[]), "66 99");
1253        assert_eq!(hex("cbtw", &[]), "66 98");
1254    }
1255
1256    #[test]
1257    fn a_shift_by_a_count_does_not_encode_the_count_because_the_machine_knows_where_it_is() {
1258        // Two arguments written and one encoded, which is the case that says why an argument
1259        // names an operand rather than being one.
1260        assert_eq!(hex("shlq", &[byte(RCX), quad(RAX)]), "48 d3 e0");
1261        assert_eq!(hex("sarl", &[byte(RCX), long(RCX)]), "d3 f9");
1262        assert_eq!(hex("shll", &[Value::Imm(3), long(RAX)]), "c1 e0 03");
1263    }
1264
1265    #[test]
1266    fn a_division_is_the_widening_and_then_the_instruction_that_names_only_its_divisor() {
1267        assert_eq!(hex("idivl", &[long(RCX)]), "f7 f9");
1268        assert_eq!(hex("idivq", &[quad(RSI)]), "48 f7 fe");
1269        assert_eq!(hex("divl", &[long(RCX)]), "f7 f1");
1270        assert_eq!(hex("negl", &[long(RAX)]), "f7 d8");
1271        assert_eq!(hex("notq", &[quad(RAX)]), "48 f7 d0");
1272    }
1273
1274    #[test]
1275    fn a_conversion_puts_its_destination_where_the_arithmetic_puts_its_source() {
1276        assert_eq!(hex("movzbl", &[byte(RAX), long(RCX)]), "0f b6 c8");
1277        assert_eq!(hex("movsbq", &[byte(RAX), quad(RCX)]), "48 0f be c8");
1278        assert_eq!(hex("movslq", &[long(RSI), quad(RAX)]), "48 63 c6");
1279        assert_eq!(hex("movzwl", &[Value::Reg(RSI, Width::Word), long(RAX)]), "0f b7 c6");
1280    }
1281
1282    #[test]
1283    fn a_mnemonic_with_arguments_it_does_not_take_is_refused_rather_than_encoded() {
1284        let mut out = Vec::new();
1285        let error = encode("ret", &[quad(RAX)], &mut out).expect_err("a return of a register");
1286        assert_eq!(error, Error::Unwritten { mnemonic: "ret".to_owned(), args: vec![Kind::Reg] });
1287        assert_eq!(out, Vec::<u8>::new(), "nothing is written for an instruction that is refused");
1288        let error = encode("frobnicate", &[], &mut out).expect_err("no such instruction");
1289        assert!(matches!(error, Error::Unwritten { .. }), "{error}");
1290        assert_eq!(encoding("addl", &[Kind::Reg], 0), None);
1291    }
1292}