Add x86 SIMD immediate shifts

This commit is contained in:
Andrew Brown
2019-11-11 11:55:04 -08:00
parent 6519a43b08
commit 1f17e35e95
5 changed files with 135 additions and 0 deletions

View File

@@ -553,6 +553,7 @@ pub(crate) fn define(
let rec_copysp = r.template("copysp");
let rec_div = r.template("div");
let rec_debugtrap = r.recipe("debugtrap");
let rec_f_ib = r.template("f_ib");
let rec_f32imm_z = r.template("f32imm_z");
let rec_f64imm_z = r.template("f64imm_z");
let rec_fa = r.template("fa");
@@ -2033,6 +2034,18 @@ pub(crate) fn define(
e.enc_32_64(x86_psra, rec_fa.opcodes(*opcodes));
}
// SIMD immediate shift
for (ty, opcodes) in &[(I16, &PS_W_IMM), (I32, &PS_D_IMM), (I64, &PS_Q_IMM)] {
let ishl_imm = ishl_imm.bind(vector(*ty, sse_vector_size));
e.enc_32_64(ishl_imm, rec_f_ib.opcodes(*opcodes).rrr(6));
let ushr_imm = ushr_imm.bind(vector(*ty, sse_vector_size));
e.enc_32_64(ushr_imm, rec_f_ib.opcodes(*opcodes).rrr(2));
let sshr_imm = sshr_imm.bind(vector(*ty, sse_vector_size));
e.enc_32_64(sshr_imm, rec_f_ib.opcodes(*opcodes).rrr(4));
}
// SIMD integer comparisons
{
use IntCC::*;

View File

@@ -431,6 +431,18 @@ pub static PSHUFB: [u8; 4] = [0x66, 0x0f, 0x38, 0x00];
/// store the result in xmm1 (SSE2).
pub static PSHUFD: [u8; 3] = [0x66, 0x0f, 0x70];
/// Shift words in xmm1 by imm8; the direction and sign-bit behavior is controlled by the RRR
/// digit used in the ModR/M byte (SSE2).
pub static PS_W_IMM: [u8; 3] = [0x66, 0x0f, 0x71];
/// Shift doublewords in xmm1 by imm8; the direction and sign-bit behavior is controlled by the RRR
/// digit used in the ModR/M byte (SSE2).
pub static PS_D_IMM: [u8; 3] = [0x66, 0x0f, 0x72];
/// Shift quadwords in xmm1 by imm8; the direction and sign-bit behavior is controlled by the RRR
/// digit used in the ModR/M byte (SSE2).
pub static PS_Q_IMM: [u8; 3] = [0x66, 0x0f, 0x73];
/// Shift words in xmm1 left by xmm2/m128 while shifting in 0s (SSE2).
pub static PSLLW: [u8; 3] = [0x66, 0x0f, 0xf1];

View File

@@ -792,6 +792,26 @@ pub(crate) fn define<'shared>(
),
);
recipes.add_template_recipe(
EncodingRecipeBuilder::new("f_ib", &formats.binary_imm, 2)
.operands_in(vec![fpr])
.operands_out(vec![0])
.inst_predicate(InstructionPredicate::new_is_signed_int(
&*formats.binary_imm,
"imm",
8,
0,
))
.emit(
r#"
{{PUT_OP}}(bits, rex1(in_reg0), sink);
modrm_r_bits(in_reg0, bits, sink);
let imm: i64 = imm.into();
sink.put1(imm as u8);
"#,
),
);
// XX /n id with 32-bit immediate sign-extended.
recipes.add_template_recipe(
EncodingRecipeBuilder::new("r_id", &formats.binary_imm, 5)