Skip to content

Commit 18d875d

Browse files
committed
asm: add implicit operands
Implicit operands are used by an instruction but not present in its disassembled output. Instructions like `mul`, e.g., will write to the `%rax` and `%rdx` registers, but this is all invisible in disassembly. Implicit operands are always fixed (i.e., the register is known), but not all fixed operands are implicit (i.e., some fixed registers _are_ disassembled).
1 parent fd6bbf7 commit 18d875d

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

cranelift/assembler-x64/meta/src/dsl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use encoding::{
1313
Encoding, Group1Prefix, Group2Prefix, Group3Prefix, Group4Prefix, Opcodes, Prefixes, Rex,
1414
};
1515
pub use features::{Feature, Features, ALL_FEATURES};
16-
pub use format::{align, fmt, r, rw, sxl, sxq, sxw, w};
16+
pub use format::{align, fmt, implicit, r, rw, sxl, sxq, sxw, w};
1717
pub use format::{Extension, Format, Location, Mutability, Operand, OperandKind};
1818

1919
/// Abbreviated constructor for an x64 instruction.

cranelift/assembler-x64/meta/src/dsl/format.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ pub fn align(location: Location) -> Operand {
7070
}
7171
}
7272

73+
/// An abbreviated constructor for an operand that is used by the instruction
74+
/// but not visible in its disassembly.
75+
pub fn implicit(location: Location) -> Operand {
76+
assert!(matches!(location.kind(), OperandKind::FixedReg(_)));
77+
Operand {
78+
implicit: true,
79+
..Operand::from(location)
80+
}
81+
}
82+
7383
/// An abbreviated constructor for a "read" operand that is sign-extended to 64
7484
/// bits (quadword).
7585
///
@@ -194,6 +204,9 @@ pub struct Operand {
194204
/// address used in the operand must align to the size of the operand (e.g.,
195205
/// `m128` must be 16-byte aligned).
196206
pub align: bool,
207+
/// Some register operands are implicit: that is, they do not appear in the
208+
/// disassembled output even though they are used in the instruction.
209+
pub implicit: bool,
197210
}
198211

199212
impl core::fmt::Display for Operand {
@@ -203,6 +216,7 @@ impl core::fmt::Display for Operand {
203216
mutability,
204217
extension,
205218
align,
219+
implicit,
206220
} = self;
207221
write!(f, "{location}")?;
208222
let mut flags = vec![];
@@ -215,6 +229,9 @@ impl core::fmt::Display for Operand {
215229
if *align != false {
216230
flags.push("align".to_owned());
217231
}
232+
if *implicit {
233+
flags.push("implicit".to_owned());
234+
}
218235
if !flags.is_empty() {
219236
write!(f, "[{}]", flags.join(","))?;
220237
}
@@ -227,11 +244,13 @@ impl From<Location> for Operand {
227244
let mutability = Mutability::default();
228245
let extension = Extension::default();
229246
let align = false;
247+
let implicit = false;
230248
Self {
231249
location,
232250
mutability,
233251
extension,
234252
align,
253+
implicit,
235254
}
236255
}
237256
}

cranelift/assembler-x64/meta/src/generate/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ impl dsl::Format {
1818
let ordered_ops: Vec<_> = self
1919
.operands
2020
.iter()
21+
.filter(|o| !o.implicit)
2122
.rev()
2223
.map(|o| format!("{{{}}}", o.location))
2324
.collect();

cranelift/assembler-x64/meta/src/generate/inst.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl dsl::Inst {
194194
f.add_block(
195195
"fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result",
196196
|f| {
197-
for op in &self.format.operands {
197+
for op in self.format.operands.iter().filter(|o| !o.implicit) {
198198
let location = op.location;
199199
let to_string = location.generate_to_string(op.extension);
200200
fmtln!(f, "let {location} = {to_string};");

0 commit comments

Comments
 (0)