From 1f5d338c04c3c06ce5b7c8a07be6609659350578 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 4 Apr 2022 14:55:36 +0800 Subject: [PATCH] powi.f64.i32 --- nac3core/src/codegen/expr.rs | 41 ++++++------------------------------ 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 5e7f5b24c..63c17b470 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -948,45 +948,16 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( } else if ty1 == ctx.primitives.float && ty2 == ctx.primitives.int32 { // Pow is the only operator that would pass typecheck between float and int assert!(*op == Operator::Pow); - // TODO: throw exception when rhs is out of i16 bound - // since llvm intrinsic only support to i16 for f64 - let i16_t = ctx.ctx.i16_type(); - let pow_intr = ctx.module.get_function("llvm.powi.f64.i16").unwrap_or_else(|| { + let i32_t = ctx.ctx.i32_type(); + let pow_intr = ctx.module.get_function("llvm.powi.f64.i32").unwrap_or_else(|| { let f64_t = ctx.ctx.f64_type(); - let ty = f64_t.fn_type(&[f64_t.into(), i16_t.into()], false); - ctx.module.add_function("llvm.powi.f64.i16", ty, None) + let ty = f64_t.fn_type(&[f64_t.into(), i32_t.into()], false); + ctx.module.add_function("llvm.powi.f64.i32", ty, None) }); - let right = ctx.builder.build_int_truncate(right.into_int_value(), i16_t, "r_pow"); - let is_neg = ctx.builder.build_int_compare( - inkwell::IntPredicate::SLT, - right, - i16_t.const_zero(), - "powi_pow_neg", - ); - let abs_intr = ctx.module.get_function("llvm.abs.i16").unwrap_or_else(|| { - let ty = i16_t.fn_type(&[i16_t.into(), ctx.ctx.bool_type().into()], false); - ctx.module.add_function("llvm.abs.i16", ty, None) - }); - let right = ctx - .builder - .build_call( - abs_intr, - &[right.into(), ctx.ctx.bool_type().const_int(0, false).into()], - "pow_abs", - ) - .try_as_basic_value() - .unwrap_left(); - let pow = ctx - .builder + ctx.builder .build_call(pow_intr, &[left.into(), right.into()], "f_pow_i") .try_as_basic_value() - .unwrap_left(); - let reciprocal = ctx.builder.build_float_div( - ctx.ctx.f64_type().const_float(1.0), - pow.into_float_value(), - "recip", - ); - ctx.builder.build_select(is_neg, reciprocal, pow.into_float_value(), "float_pow_i") + .unwrap_left() } else { unimplemented!() }