Factor out fcmp and icmp translation into helper functions.

This commit is contained in:
Dan Gohman
2018-03-13 05:56:59 -07:00
parent 2d1f9f874c
commit c333a52e3e

View File

@@ -765,101 +765,45 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
}
/**************************** Comparison Operators **********************************/
Operator::I32LtS | Operator::I64LtS => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::SignedLessThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::SignedLessThan, builder, state)
}
Operator::I32LtU | Operator::I64LtU => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::UnsignedLessThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::UnsignedLessThan, builder, state)
}
Operator::I32LeS | Operator::I64LeS => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::SignedLessThanOrEqual, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::SignedLessThanOrEqual, builder, state)
}
Operator::I32LeU | Operator::I64LeU => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(
IntCC::UnsignedLessThanOrEqual,
arg1,
arg2,
);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::UnsignedLessThanOrEqual, builder, state)
}
Operator::I32GtS | Operator::I64GtS => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::SignedGreaterThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::SignedGreaterThan, builder, state)
}
Operator::I32GtU | Operator::I64GtU => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::UnsignedGreaterThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::UnsignedGreaterThan, builder, state)
}
Operator::I32GeS | Operator::I64GeS => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(
IntCC::SignedGreaterThanOrEqual,
arg1,
arg2,
);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::SignedGreaterThanOrEqual, builder, state)
}
Operator::I32GeU | Operator::I64GeU => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(
IntCC::UnsignedGreaterThanOrEqual,
arg1,
arg2,
);
state.push1(builder.ins().bint(I32, val));
translate_icmp(IntCC::UnsignedGreaterThanOrEqual, builder, state)
}
Operator::I32Eqz | Operator::I64Eqz => {
let arg = state.pop1();
let val = builder.ins().icmp_imm(IntCC::Equal, arg, 0);
state.push1(builder.ins().bint(I32, val));
}
Operator::I32Eq | Operator::I64Eq => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::Equal, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::F32Eq | Operator::F64Eq => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::Equal, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::I32Ne | Operator::I64Ne => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().icmp(IntCC::NotEqual, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::F32Ne | Operator::F64Ne => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::NotEqual, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::F32Gt | Operator::F64Gt => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::GreaterThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::I32Eq | Operator::I64Eq => translate_icmp(IntCC::Equal, builder, state),
Operator::F32Eq | Operator::F64Eq => translate_fcmp(FloatCC::Equal, builder, state),
Operator::I32Ne | Operator::I64Ne => translate_icmp(IntCC::NotEqual, builder, state),
Operator::F32Ne | Operator::F64Ne => translate_fcmp(FloatCC::NotEqual, builder, state),
Operator::F32Gt | Operator::F64Gt => translate_fcmp(FloatCC::GreaterThan, builder, state),
Operator::F32Ge | Operator::F64Ge => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::GreaterThanOrEqual, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
}
Operator::F32Lt | Operator::F64Lt => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::LessThan, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_fcmp(FloatCC::GreaterThanOrEqual, builder, state)
}
Operator::F32Lt | Operator::F64Lt => translate_fcmp(FloatCC::LessThan, builder, state),
Operator::F32Le | Operator::F64Le => {
let (arg1, arg2) = state.pop2();
let val = builder.ins().fcmp(FloatCC::LessThanOrEqual, arg1, arg2);
state.push1(builder.ins().bint(I32, val));
translate_fcmp(FloatCC::LessThanOrEqual, builder, state)
}
Operator::Wake { .. } |
Operator::I32Wait { .. } |
@@ -1101,3 +1045,23 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
base,
);
}
fn translate_icmp(
cc: IntCC,
builder: &mut FunctionBuilder<Variable>,
state: &mut TranslationState,
) {
let (arg0, arg1) = state.pop2();
let val = builder.ins().icmp(cc, arg0, arg1);
state.push1(builder.ins().bint(I32, val));
}
fn translate_fcmp(
cc: FloatCC,
builder: &mut FunctionBuilder<Variable>,
state: &mut TranslationState,
) {
let (arg0, arg1) = state.pop2();
let val = builder.ins().fcmp(cc, arg0, arg1);
state.push1(builder.ins().bint(I32, val));
}