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}