Add x86 pack instructions

This commit is contained in:
Andrew Brown
2020-03-25 10:16:07 -07:00
parent 341dc45cea
commit fb6e8f784d
6 changed files with 63 additions and 2 deletions

View File

@@ -1619,6 +1619,7 @@ fn define_simd(
let x86_insertps = x86.by_name("x86_insertps");
let x86_movlhps = x86.by_name("x86_movlhps");
let x86_movsd = x86.by_name("x86_movsd");
let x86_packss = x86.by_name("x86_packss");
let x86_pextr = x86.by_name("x86_pextr");
let x86_pinsr = x86.by_name("x86_pinsr");
let x86_pmaxs = x86.by_name("x86_pmaxs");
@@ -1804,6 +1805,10 @@ fn define_simd(
rec_fa.opcodes(low),
);
}
for (ty, opcodes) in &[(I16, &PACKSSWB), (I32, &PACKSSDW)] {
let x86_packss = x86_packss.bind(vector(*ty, sse_vector_size));
e.enc_both_inferred(x86_packss, rec_fa.opcodes(*opcodes));
}
// SIMD bitcast all 128-bit vectors to each other (for legalizing splat.x16x8).
for from_type in ValueType::all_lane_types().filter(allowed_simd_type) {

View File

@@ -6,7 +6,6 @@ use crate::cdsl::instructions::{
use crate::cdsl::operands::Operand;
use crate::cdsl::types::ValueType;
use crate::cdsl::typevar::{Interval, TypeSetBuilder, TypeVar};
use crate::shared::entities::EntityRefs;
use crate::shared::formats::Formats;
use crate::shared::immediates::Immediates;
@@ -275,7 +274,7 @@ pub(crate) fn define(
);
let a = &Operand::new("a", TxN).with_doc("A vector value (i.e. held in an XMM register)");
let b = &Operand::new("b", TxN).with_doc("A vector value (i.e. held in an XMM register)");
let i = &Operand::new("i", uimm8,).with_doc( "An ordering operand controlling the copying of data from the source to the destination; see PSHUFD in Intel manual for details");
let i = &Operand::new("i", uimm8).with_doc("An ordering operand controlling the copying of data from the source to the destination; see PSHUFD in Intel manual for details");
ig.push(
Inst::new(
@@ -410,6 +409,35 @@ pub(crate) fn define(
.operands_out(vec![a]),
);
let I16xN = &TypeVar::new(
"I16xN",
"A SIMD vector type containing integers 16-bits wide and up",
TypeSetBuilder::new()
.ints(16..32)
.simd_lanes(4..8)
.includes_scalars(false)
.build(),
);
let x = &Operand::new("x", I16xN);
let y = &Operand::new("y", I16xN);
let a = &Operand::new("a", &I16xN.split_lanes());
ig.push(
Inst::new(
"x86_packss",
r#"
Convert packed signed integers the lanes of ``x`` and ``y`` into half-width integers, using
signed saturation to handle overflows. For example, with notional i16x2 vectors, where
``x = [x1, x0]`` and ``y = [y1, y0]``, this operation would result in
``a = [y1', y0', x1', x0']`` (using the Intel manual's right-to-left lane ordering).
"#,
&formats.binary,
)
.operands_in(vec![x, y])
.operands_out(vec![a]),
);
let x = &Operand::new("x", FxN);
let y = &Operand::new("y", FxN);
let a = &Operand::new("a", FxN);

View File

@@ -291,6 +291,14 @@ pub static OR_IMM8_SIGN_EXTEND: [u8; 1] = [0x83];
/// Return the bitwise logical OR of packed single-precision values in xmm and x/m (SSE).
pub static ORPS: [u8; 2] = [0x0f, 0x56];
/// Converts 8 packed signed word integers from xmm1 and from xxm2/m128 into 16 packed signed byte
/// integers in xmm1 using signed saturation (SSE2).
pub static PACKSSWB: [u8; 3] = [0x66, 0x0f, 0x63];
/// Converts 4 packed signed doubleword integers from xmm1 and from xmm2/m128 into 8 packed signed
/// word integers in xmm1 using signed saturation (SSE2).
pub static PACKSSDW: [u8; 3] = [0x66, 0x0f, 0x6b];
/// Add packed byte integers from xmm2/m128 and xmm1 (SSE2).
pub static PADDB: [u8; 3] = [0x66, 0x0f, 0xfc];