Skip to content

Commit 3fafbe0

Browse files
alexcrichtonbongjunj
authored andcommitted
x64: Add EVEX shifts to the new assembler (bytecodealliance#11270)
* x64: Add EVEX shifts to the new assembler This commit adds bindings for the EVEX encodings of `vps{ll,ra,rl}{d,q}` to the new assembler. Currently the 16-bit shifts `vps{ll,ra,rl}w` are omitted due to the `avx512bw` feature not yet being bound in Cranelift. In implementing these instructions a few refactorings/fixes were necessary: * Primarily all EVEX instructions now need to be defined not only with their vector length but also their "tuple type" found in encoding tables. This is required to correctly handle the 8-bit displacement scaling that happens with EVEX instructions. * Some small helpers to the `Evex` structure were added such as `Evex::digit` and `Evex::ib`. * The `evex_scaling` factor is now calculated in `generate_evex_prefix` according to the instruction format itself. * The VEX and EVEX `generate_*_prefix` functions now delegate to a shared function to handle the same operand formats across both of them. * Fuzz generation of `AmodeOffset` is now updated to bias to some "interesting" offsets that exercise the cases where EVEX scaling is necessary. * The ISLE `XmmUnaryRmRImmEvex` instruction format was removed as it's no longer necessary. * Fix emit tests
1 parent f69d518 commit 3fafbe0

File tree

16 files changed

+277
-157
lines changed

16 files changed

+277
-157
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 custom::{Custom, Customization};
1313
pub use encoding::{Encoding, ModRmKind, OpcodeMod};
1414
pub use encoding::{Evex, Length, Vex, VexEscape, VexPrefix, evex, vex};
1515
pub use encoding::{
16-
Group1Prefix, Group2Prefix, Group3Prefix, Group4Prefix, Opcodes, Prefixes, Rex, rex,
16+
Group1Prefix, Group2Prefix, Group3Prefix, Group4Prefix, Opcodes, Prefixes, Rex, TupleType, rex,
1717
};
1818
pub use features::{ALL_FEATURES, Feature, Features};
1919
pub use format::{Eflags, Extension, Format, Location, Mutability, Operand, OperandKind, RegClass};

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

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn vex(length: Length) -> Vex {
4747

4848
/// An abbreviated constructor for EVEX-encoded instructions.
4949
#[must_use]
50-
pub fn evex(length: Length) -> Evex {
50+
pub fn evex(length: Length, tuple_type: TupleType) -> Evex {
5151
Evex {
5252
length,
5353
pp: None,
@@ -56,6 +56,7 @@ pub fn evex(length: Length) -> Evex {
5656
opcode: u8::MAX,
5757
modrm: None,
5858
imm: Imm::None,
59+
tuple_type,
5960
}
6061
}
6162

@@ -1243,6 +1244,9 @@ pub struct Evex {
12431244
pub modrm: Option<ModRmKind>,
12441245
/// See [`Rex.imm`](Rex.imm).
12451246
pub imm: Imm,
1247+
/// The "Tuple Type" corresponding to scaling of the 8-bit displacement
1248+
/// parameter for memory operands. See [`TupleType`] for more information.
1249+
pub tuple_type: TupleType,
12461250
}
12471251

12481252
impl Evex {
@@ -1361,6 +1365,36 @@ impl Evex {
13611365
_ => None,
13621366
}
13631367
}
1368+
1369+
/// Set the digit extending the opcode; equivalent to `/<digit>` in the
1370+
/// reference manual.
1371+
///
1372+
/// # Panics
1373+
///
1374+
/// Panics if `extension` is too large.
1375+
#[must_use]
1376+
pub fn digit(self, extension: u8) -> Self {
1377+
assert!(extension <= 0b111, "must fit in 3 bits");
1378+
Self {
1379+
modrm: Some(ModRmKind::Digit(extension)),
1380+
..self
1381+
}
1382+
}
1383+
1384+
/// Append a byte-sized immediate operand (8-bit); equivalent to `ib` in the
1385+
/// reference manual.
1386+
///
1387+
/// # Panics
1388+
///
1389+
/// Panics if an immediate operand is already set.
1390+
#[must_use]
1391+
pub fn ib(self) -> Self {
1392+
assert_eq!(self.imm, Imm::None);
1393+
Self {
1394+
imm: Imm::ib,
1395+
..self
1396+
}
1397+
}
13641398
}
13651399

13661400
impl From<Evex> for Encoding {
@@ -1388,3 +1422,25 @@ impl fmt::Display for Evex {
13881422
Ok(())
13891423
}
13901424
}
1425+
1426+
/// Tuple Type definitions used in EVEX encodings.
1427+
///
1428+
/// This enumeration corresponds to table 2-34 and 2-35 in the Intel manual.
1429+
/// This is a property of all instruction formats listed in the encoding table
1430+
/// for each instruction.
1431+
#[expect(missing_docs, reason = "matching manual names")]
1432+
pub enum TupleType {
1433+
Full,
1434+
Half,
1435+
FullMem,
1436+
Tuple1Scalar,
1437+
Tuple1Fixed,
1438+
Tuple2,
1439+
Tuple4,
1440+
Tuple8,
1441+
HalfMem,
1442+
QuarterMem,
1443+
EigthMem,
1444+
Mem128,
1445+
Movddup,
1446+
}

0 commit comments

Comments
 (0)