Replace ExtractLane format with BinaryImm8

Like https://github.com/bytecodealliance/wasmtime/pull/1762, this change the name of the `ExtractLane` format to the more-general `BinaryImm8` and renames its immediate argument from `lane` to `imm`.
This commit is contained in:
Andrew Brown
2020-05-27 09:24:46 -07:00
parent 7d6e94b952
commit a27a079d65
9 changed files with 36 additions and 39 deletions

View File

@@ -283,7 +283,7 @@ pub(crate) fn define(
Packed Shuffle Doublewords -- copies data from either memory or lanes in an extended Packed Shuffle Doublewords -- copies data from either memory or lanes in an extended
register and re-orders the data according to the passed immediate byte. register and re-orders the data according to the passed immediate byte.
"#, "#,
&formats.extract_lane, &formats.binary_imm8,
) )
.operands_in(vec![a, i]) // TODO allow copying from memory here (need more permissive type than TxN) .operands_in(vec![a, i]) // TODO allow copying from memory here (need more permissive type than TxN)
.operands_out(vec![a]), .operands_out(vec![a]),
@@ -314,7 +314,7 @@ pub(crate) fn define(
The lane index, ``Idx``, is an immediate value, not an SSA value. It The lane index, ``Idx``, is an immediate value, not an SSA value. It
must indicate a valid lane index for the type of ``x``. must indicate a valid lane index for the type of ``x``.
"#, "#,
&formats.extract_lane, &formats.binary_imm8,
) )
.operands_in(vec![x, Idx]) .operands_in(vec![x, Idx])
.operands_out(vec![a]), .operands_out(vec![a]),

View File

@@ -996,20 +996,20 @@ pub(crate) fn define<'shared>(
// XX /r ib with 8-bit unsigned immediate (e.g. for pshufd) // XX /r ib with 8-bit unsigned immediate (e.g. for pshufd)
{ {
recipes.add_template_inferred( recipes.add_template_inferred(
EncodingRecipeBuilder::new("r_ib_unsigned_fpr", &formats.extract_lane, 2) EncodingRecipeBuilder::new("r_ib_unsigned_fpr", &formats.binary_imm8, 2)
.operands_in(vec![fpr]) .operands_in(vec![fpr])
.operands_out(vec![fpr]) .operands_out(vec![fpr])
.inst_predicate(InstructionPredicate::new_is_unsigned_int( .inst_predicate(InstructionPredicate::new_is_unsigned_int(
&*formats.extract_lane, &*formats.binary_imm8,
"lane", "imm",
8, 8,
0, 0,
)) // TODO if the format name is changed then "lane" should be renamed to something more appropriate--ordering mask? broadcast immediate? ))
.emit( .emit(
r#" r#"
{{PUT_OP}}(bits, rex2(in_reg0, out_reg0), sink); {{PUT_OP}}(bits, rex2(in_reg0, out_reg0), sink);
modrm_rr(in_reg0, out_reg0, sink); modrm_rr(in_reg0, out_reg0, sink);
let imm:i64 = lane.into(); let imm: i64 = imm.into();
sink.put1(imm as u8); sink.put1(imm as u8);
"#, "#,
), ),
@@ -1020,17 +1020,17 @@ pub(crate) fn define<'shared>(
// XX /r ib with 8-bit unsigned immediate (e.g. for extractlane) // XX /r ib with 8-bit unsigned immediate (e.g. for extractlane)
{ {
recipes.add_template_inferred( recipes.add_template_inferred(
EncodingRecipeBuilder::new("r_ib_unsigned_gpr", &formats.extract_lane, 2) EncodingRecipeBuilder::new("r_ib_unsigned_gpr", &formats.binary_imm8, 2)
.operands_in(vec![fpr]) .operands_in(vec![fpr])
.operands_out(vec![gpr]) .operands_out(vec![gpr])
.inst_predicate(InstructionPredicate::new_is_unsigned_int( .inst_predicate(InstructionPredicate::new_is_unsigned_int(
&*formats.extract_lane, "lane", 8, 0, &*formats.binary_imm8, "imm", 8, 0,
)) ))
.emit( .emit(
r#" r#"
{{PUT_OP}}(bits, rex2(out_reg0, in_reg0), sink); {{PUT_OP}}(bits, rex2(out_reg0, in_reg0), sink);
modrm_rr(out_reg0, in_reg0, sink); // note the flipped register in the ModR/M byte modrm_rr(out_reg0, in_reg0, sink); // note the flipped register in the ModR/M byte
let imm:i64 = lane.into(); let imm: i64 = imm.into();
sink.put1(imm as u8); sink.put1(imm as u8);
"#, "#,
), "size_with_inferred_rex_for_inreg0_outreg0" ), "size_with_inferred_rex_for_inreg0_outreg0"

View File

@@ -17,7 +17,7 @@ pub(crate) struct Formats {
pub(crate) cond_trap: Rc<InstructionFormat>, pub(crate) cond_trap: Rc<InstructionFormat>,
pub(crate) copy_special: Rc<InstructionFormat>, pub(crate) copy_special: Rc<InstructionFormat>,
pub(crate) copy_to_ssa: Rc<InstructionFormat>, pub(crate) copy_to_ssa: Rc<InstructionFormat>,
pub(crate) extract_lane: Rc<InstructionFormat>, pub(crate) binary_imm8: Rc<InstructionFormat>,
pub(crate) float_compare: Rc<InstructionFormat>, pub(crate) float_compare: Rc<InstructionFormat>,
pub(crate) float_cond: Rc<InstructionFormat>, pub(crate) float_cond: Rc<InstructionFormat>,
pub(crate) float_cond_trap: Rc<InstructionFormat>, pub(crate) float_cond_trap: Rc<InstructionFormat>,
@@ -76,6 +76,8 @@ impl Formats {
binary: Builder::new("Binary").value().value().build(), binary: Builder::new("Binary").value().value().build(),
binary_imm8: Builder::new("BinaryImm8").value().imm(&imm.uimm8).build(),
binary_imm: Builder::new("BinaryImm").value().imm(&imm.imm64).build(), binary_imm: Builder::new("BinaryImm").value().imm(&imm.imm64).build(),
// The select instructions are controlled by the second VALUE operand. // The select instructions are controlled by the second VALUE operand.
@@ -100,11 +102,6 @@ impl Formats {
nullary: Builder::new("NullAry").build(), nullary: Builder::new("NullAry").build(),
extract_lane: Builder::new("ExtractLane")
.value()
.imm_with_name("lane", &imm.uimm8)
.build(),
shuffle: Builder::new("Shuffle") shuffle: Builder::new("Shuffle")
.value() .value()
.value() .value()

View File

@@ -579,7 +579,7 @@ fn define_simd_lane_access(
may or may not be zeroed depending on the ISA but the type system should prevent using may or may not be zeroed depending on the ISA but the type system should prevent using
``a`` as anything other than the extracted value. ``a`` as anything other than the extracted value.
"#, "#,
&formats.extract_lane, &formats.binary_imm8,
) )
.operands_in(vec![x, Idx]) .operands_in(vec![x, Idx])
.operands_out(vec![a]), .operands_out(vec![a]),

View File

@@ -1195,10 +1195,10 @@ fn convert_extractlane(
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst); pos.use_srcloc(inst);
if let ir::InstructionData::ExtractLane { if let ir::InstructionData::BinaryImm8 {
opcode: ir::Opcode::Extractlane, opcode: ir::Opcode::Extractlane,
arg, arg,
lane, imm: lane,
} = pos.func.dfg[inst] } = pos.func.dfg[inst]
{ {
// NOTE: the following legalization assumes that the upper bits of the XMM register do // NOTE: the following legalization assumes that the upper bits of the XMM register do

View File

@@ -756,10 +756,10 @@ impl<'a> Verifier<'a> {
| UnaryIeee64 { .. } | UnaryIeee64 { .. }
| UnaryBool { .. } | UnaryBool { .. }
| Binary { .. } | Binary { .. }
| BinaryImm8 { .. }
| BinaryImm { .. } | BinaryImm { .. }
| Ternary { .. } | Ternary { .. }
| TernaryImm8 { .. } | TernaryImm8 { .. }
| ExtractLane { .. }
| Shuffle { .. } | Shuffle { .. }
| IntCompare { .. } | IntCompare { .. }
| IntCompareImm { .. } | IntCompareImm { .. }
@@ -1912,9 +1912,9 @@ impl<'a> Verifier<'a> {
Ok(()) Ok(())
} }
} }
ir::InstructionData::ExtractLane { ir::InstructionData::BinaryImm8 {
opcode: ir::instructions::Opcode::Extractlane, opcode: ir::instructions::Opcode::Extractlane,
lane, imm: lane,
arg, arg,
.. ..
} }

View File

@@ -508,6 +508,7 @@ pub fn write_operands(
constant_handle, .. constant_handle, ..
} => write!(w, " {}", constant_handle), } => write!(w, " {}", constant_handle),
Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]), Binary { args, .. } => write!(w, " {}, {}", args[0], args[1]),
BinaryImm8 { arg, imm, .. } => write!(w, " {}, {}", arg, imm),
BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm), BinaryImm { arg, imm, .. } => write!(w, " {}, {}", arg, imm),
Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]), Ternary { args, .. } => write!(w, " {}, {}, {}", args[0], args[1], args[2]),
MultiAry { ref args, .. } => { MultiAry { ref args, .. } => {
@@ -519,7 +520,6 @@ pub fn write_operands(
} }
NullAry { .. } => write!(w, " "), NullAry { .. } => write!(w, " "),
TernaryImm8 { imm, args, .. } => write!(w, " {}, {}, {}", args[0], args[1], imm), TernaryImm8 { imm, args, .. } => write!(w, " {}, {}, {}", args[0], args[1], imm),
ExtractLane { lane, arg, .. } => write!(w, " {}, {}", arg, lane),
Shuffle { mask, args, .. } => { Shuffle { mask, args, .. } => {
let data = dfg.immediates.get(mask).expect( let data = dfg.immediates.get(mask).expect(
"Expected the shuffle mask to already be inserted into the immediates table", "Expected the shuffle mask to already be inserted into the immediates table",

View File

@@ -2752,6 +2752,12 @@ impl<'a> Parser<'a> {
args: [lhs, rhs], args: [lhs, rhs],
} }
} }
InstructionFormat::BinaryImm8 => {
let arg = self.match_value("expected SSA value first operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?;
let imm = self.match_uimm8("expected unsigned 8-bit immediate")?;
InstructionData::BinaryImm8 { opcode, arg, imm }
}
InstructionFormat::BinaryImm => { InstructionFormat::BinaryImm => {
let lhs = self.match_value("expected SSA value first operand")?; let lhs = self.match_value("expected SSA value first operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?; self.match_token(Token::Comma, "expected ',' between operands")?;
@@ -2899,12 +2905,6 @@ impl<'a> Parser<'a> {
args: [lhs, rhs], args: [lhs, rhs],
} }
} }
InstructionFormat::ExtractLane => {
let arg = self.match_value("expected SSA value last operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?;
let lane = self.match_uimm8("expected lane number")?;
InstructionData::ExtractLane { opcode, lane, arg }
}
InstructionFormat::Shuffle => { InstructionFormat::Shuffle => {
let a = self.match_value("expected SSA value first operand")?; let a = self.match_value("expected SSA value first operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?; self.match_token(Token::Comma, "expected ',' between operands")?;

View File

@@ -32,6 +32,11 @@ pub enum SerInstData {
opcode: String, opcode: String,
args: [String; 2], args: [String; 2],
}, },
BinaryImm8 {
opcode: String,
arg: String,
imm: String,
},
BinaryImm { BinaryImm {
opcode: String, opcode: String,
arg: String, arg: String,
@@ -53,11 +58,6 @@ pub enum SerInstData {
NullAry { NullAry {
opcode: String, opcode: String,
}, },
ExtractLane {
opcode: String,
arg: String,
lane: String,
},
Shuffle { Shuffle {
opcode: String, opcode: String,
args: [String; 2], args: [String; 2],
@@ -292,6 +292,11 @@ pub fn get_inst_data(inst_index: Inst, func: &Function) -> SerInstData {
args: hold_args, args: hold_args,
} }
} }
InstructionData::BinaryImm8 { opcode, arg, imm } => SerInstData::BinaryImm8 {
opcode: opcode.to_string(),
arg: arg.to_string(),
imm: imm.to_string(),
},
InstructionData::BinaryImm { opcode, arg, imm } => SerInstData::BinaryImm { InstructionData::BinaryImm { opcode, arg, imm } => SerInstData::BinaryImm {
opcode: opcode.to_string(), opcode: opcode.to_string(),
arg: arg.to_string(), arg: arg.to_string(),
@@ -331,11 +336,6 @@ pub fn get_inst_data(inst_index: Inst, func: &Function) -> SerInstData {
imm: imm.to_string(), imm: imm.to_string(),
} }
} }
InstructionData::ExtractLane { opcode, arg, lane } => SerInstData::ExtractLane {
opcode: opcode.to_string(),
arg: arg.to_string(),
lane: lane.to_string(),
},
InstructionData::UnaryConst { InstructionData::UnaryConst {
opcode, opcode,
constant_handle, constant_handle,