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]:
|
for binop in [sdiv_imm, srem_imm]:
|
||||||
widen_imm(True, binop)
|
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)
|
widen_imm(False, irsub_imm)
|
||||||
|
|
||||||
# bit ops
|
# bit ops
|
||||||
@@ -492,6 +475,26 @@ expand.legalize(
|
|||||||
b << bor(b1, b2)
|
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.
|
# Expansions for immediate operands that are out of range.
|
||||||
for inst_imm, inst in [
|
for inst_imm, inst in [
|
||||||
(iadd_imm, iadd),
|
(iadd_imm, iadd),
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ fn verify_polymorphic(
|
|||||||
let tv = operands_in[op_num].type_var().unwrap();
|
let tv = operands_in[op_num].type_var().unwrap();
|
||||||
let free_typevar = tv.free_typevar();
|
let free_typevar = tv.free_typevar();
|
||||||
if (free_typevar.is_some() && tv == &free_typevar.unwrap())
|
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) {
|
match verify_ctrl_typevar(tv, &value_opnums, &operands_in, &operands_out) {
|
||||||
Ok(typevars) => {
|
Ok(typevars) => {
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
|
|||||||
let f32const = insts.by_name("f32const");
|
let f32const = insts.by_name("f32const");
|
||||||
let f64const = insts.by_name("f64const");
|
let f64const = insts.by_name("f64const");
|
||||||
let fcopysign = insts.by_name("fcopysign");
|
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 fneg = insts.by_name("fneg");
|
||||||
let iadd = insts.by_name("iadd");
|
let iadd = insts.by_name("iadd");
|
||||||
let iadd_carry = insts.by_name("iadd_carry");
|
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.
|
// Expansions for immediate operands that are out of range.
|
||||||
for &(inst_imm, inst) in &[
|
for &(inst_imm, inst) in &[
|
||||||
(iadd_imm, iadd),
|
(iadd_imm, iadd),
|
||||||
|
|||||||
Reference in New Issue
Block a user