use cranelift_codegen::ir;
use cranelift_codegen::ir::InstBuilder;
use cranelift_codegen::ir::types::{I32, I64};
use cranelift_frontend::FunctionBuilder;
#[derive(Clone, Copy)]
pub struct ControlEffect(ir::Value);
impl ControlEffect {
pub fn signal(&self, builder: &mut FunctionBuilder) -> ir::Value {
builder.ins().ushr_imm(self.0, 32)
}
pub fn from_u64(val: ir::Value) -> Self {
Self(val)
}
pub fn to_u64(&self) -> ir::Value {
self.0
}
pub fn encode_resume(builder: &mut FunctionBuilder) -> Self {
let discriminant = builder.ins().iconst(
I64,
i64::from(wasmtime_environ::CONTROL_EFFECT_RESUME_DISCRIMINANT),
);
let val = builder.ins().ishl_imm(discriminant, 32);
Self(val)
}
pub fn encode_switch(builder: &mut FunctionBuilder) -> Self {
let discriminant = builder.ins().iconst(
I64,
i64::from(wasmtime_environ::CONTROL_EFFECT_SWITCH_DISCRIMINANT),
);
let val = builder.ins().ishl_imm(discriminant, 32);
Self(val)
}
pub fn encode_suspend(builder: &mut FunctionBuilder, handler_index: ir::Value) -> Self {
let discriminant = builder.ins().iconst(
I64,
i64::from(wasmtime_environ::CONTROL_EFFECT_SUSPEND_DISCRIMINANT),
);
let val = builder.ins().ishl_imm(discriminant, 32);
let handler_index = builder.ins().uextend(I64, handler_index);
let val = builder.ins().bor(val, handler_index);
Self(val)
}
pub fn handler_index(self, builder: &mut FunctionBuilder) -> ir::Value {
builder.ins().ireduce(I32, self.0)
}
}