Open doug-q opened 3 weeks ago
I do have a small amount of progress here
fn emit_icmp<'c, H: HugrView>(
context: &mut EmitFuncContext<'c, H>,
args: EmitOpArgs<'c, CustomOp, H>,
pred: inkwell::IntPredicate,
) -> Result<()> {
let true_val = emit_value(context, &Value::true_val())?;
let false_val = emit_value(context, &Value::false_val())?;
let builder = context.builder();
let [lhs, rhs] = TryInto::<[_; 2]>::try_into(args.inputs).unwrap();
let a = builder.build_int_compare(pred, lhs.into_int_value(), rhs.into_int_value(), "")?;
let a = builder.build_select(a, true_val, false_val, "")?;
args.outputs.finish(builder, [a.into()])
}
impl<'c, H: HugrView> EmitOp<'c, CustomOp, H> for IntOpEmitter<'c, '_, H> {
fn emit(&mut self, args: EmitOpArgs<'c, CustomOp, H>) -> Result<()> {
let iot = ConcreteIntOp::from_optype(&args.node().generalise())
.ok_or(anyhow!("IntOpEmitter from_optype_failed"))?;
match iot.name().as_str() {
"iadd" => {
let builder = self.0.builder();
let [lhs, rhs] = TryInto::<[_; 2]>::try_into(args.inputs).unwrap();
let a = builder.build_int_add(lhs.into_int_value(), rhs.into_int_value(), "")?;
args.outputs.finish(builder, [a.into()])
}
"ieq" => {
emit_icmp(self.0, args, inkwell::IntPredicate::EQ)
}
"ilt_s" => {
emit_icmp(self.0, args, inkwell::IntPredicate::SLT)
}
"isub" => {
let builder = self.0.builder();
let [lhs, rhs] = TryInto::<[_; 2]>::try_into(args.inputs).unwrap();
let a = builder.build_int_sub(lhs.into_int_value(), rhs.into_int_value(), "")?;
args.outputs.finish(builder, [a.into()])
}
n => Err(anyhow!("IntOpEmitter: unknown name: {n}")),
}
}
}
See https://github.com/CQCL/hugr/blob/main/specification/hugr.md#arithmeticint for the spec of these ops.