Add Rust implementation and address review comments of #742;
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user