Add Rust implementation and address review comments of #742;

This commit is contained in:
Benjamin Bouvier
2019-05-17 17:16:52 +02:00
parent 71a345e813
commit 97ebaa6f37
3 changed files with 49 additions and 18 deletions

View File

@@ -261,23 +261,6 @@ for binop in [iadd_imm, imul_imm, udiv_imm, urem_imm]:
for binop in [sdiv_imm, srem_imm]:
widen_imm(True, binop)
# Use expand instead of widen, because widen only gets applied for i8 and i16
# base type vars, but these take f32 and f64 as base type var.
for ty in [types.f32, types.f64]:
for int_ty in [types.i8, types.i16]:
expand.legalize(
a << insts.fcvt_from_uint.bind(ty).bind(int_ty)(b),
Rtl(
x << uextend.i32(b),
a << insts.fcvt_from_uint.bind(ty).i32(x),
))
expand.legalize(
a << insts.fcvt_from_sint.bind(ty).bind(int_ty)(b),
Rtl(
x << sextend.i32(b),
a << insts.fcvt_from_sint.bind(ty).i32(x),
))
widen_imm(False, irsub_imm)
# bit ops
@@ -492,6 +475,26 @@ expand.legalize(
b << bor(b1, b2)
))
# Expansions for fcvt_from_{u,s}int for smaller integer types.
# These use expand and not widen because the controlling type variable for
# these instructions are f32/f64, which are legalized as part of the expand
# group.
for dest_ty in [types.f32, types.f64]:
for src_ty in [types.i8, types.i16]:
expand.legalize(
a << insts.fcvt_from_uint.bind(dest_ty).bind(src_ty)(b),
Rtl(
x << uextend.i32(b),
a << insts.fcvt_from_uint.bind(dest_ty).i32(x),
))
expand.legalize(
a << insts.fcvt_from_sint.bind(dest_ty).bind(src_ty)(b),
Rtl(
x << sextend.i32(b),
a << insts.fcvt_from_sint.bind(dest_ty).i32(x),
))
# Expansions for immediate operands that are out of range.
for inst_imm, inst in [
(iadd_imm, iadd),

View File

@@ -373,7 +373,7 @@ fn verify_polymorphic(
let tv = operands_in[op_num].type_var().unwrap();
let free_typevar = tv.free_typevar();
if (free_typevar.is_some() && tv == &free_typevar.unwrap())
|| !tv.singleton_type().is_none()
|| tv.singleton_type().is_some()
{
match verify_ctrl_typevar(tv, &value_opnums, &operands_in, &operands_out) {
Ok(typevars) => {

View File

@@ -62,6 +62,8 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
let f32const = insts.by_name("f32const");
let f64const = insts.by_name("f64const");
let fcopysign = insts.by_name("fcopysign");
let fcvt_from_sint = insts.by_name("fcvt_from_sint");
let fcvt_from_uint = insts.by_name("fcvt_from_uint");
let fneg = insts.by_name("fneg");
let iadd = insts.by_name("iadd");
let iadd_carry = insts.by_name("iadd_carry");
@@ -512,6 +514,32 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
],
);
// Expansions for fcvt_from_{u,s}int for smaller integer types.
// These use expand and not widen because the controlling type variable for
// these instructions are f32/f64, which are legalized as part of the expand
// group.
for &dest_ty in &[F32, F64] {
for &src_ty in &[I8, I16] {
let bound_inst = bind(bind(fcvt_from_uint, dest_ty), src_ty);
expand.legalize(
def!(a = bound_inst(b)),
vec![
def!(x = uextend.I32(b)),
def!(a = fcvt_from_uint.dest_ty(x)),
],
);
let bound_inst = bind(bind(fcvt_from_sint, dest_ty), src_ty);
expand.legalize(
def!(a = bound_inst(b)),
vec![
def!(x = sextend.I32(b)),
def!(a = fcvt_from_sint.dest_ty(x)),
],
);
}
}
// Expansions for immediate operands that are out of range.
for &(inst_imm, inst) in &[
(iadd_imm, iadd),