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