[core] codegen: Add bool_to_int_type to replace bool_to_{i1,i8}
Unifies the implementation for both functions.
This commit is contained in:
parent
f52ba9f151
commit
529fa67855
@ -2001,7 +2001,7 @@ pub fn gen_cmpop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
).into_int_value();
|
||||
let result = call_string_eq(ctx, lhs_ptr, lhs_len, rhs_ptr, rhs_len);
|
||||
if *op == Cmpop::NotEq {
|
||||
ctx.builder.build_not(result, "").unwrap()
|
||||
ctx.builder.build_not(result, "").unwrap()
|
||||
} else {
|
||||
result
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use inkwell::{
|
||||
|
||||
use nac3parser::ast::{Expr, Stmt, StrRef};
|
||||
|
||||
use super::{bool_to_i1, bool_to_i8, expr::*, stmt::*, values::ArraySliceValue, CodeGenContext};
|
||||
use super::{bool_to_int_type, expr::*, stmt::*, values::ArraySliceValue, CodeGenContext};
|
||||
use crate::{
|
||||
symbol_resolver::ValueEnum,
|
||||
toplevel::{DefinitionId, TopLevelDef},
|
||||
@ -248,22 +248,32 @@ pub trait CodeGenerator {
|
||||
gen_block(self, ctx, stmts)
|
||||
}
|
||||
|
||||
/// See [`bool_to_i1`].
|
||||
/// Converts the value of a boolean-like value `bool_value` into an `i1`.
|
||||
fn bool_to_i1<'ctx>(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
bool_value: IntValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
bool_to_i1(&ctx.builder, bool_value)
|
||||
self.bool_to_int_type(ctx, bool_value, ctx.ctx.bool_type())
|
||||
}
|
||||
|
||||
/// See [`bool_to_i8`].
|
||||
/// Converts the value of a boolean-like value `bool_value` into an `i8`.
|
||||
fn bool_to_i8<'ctx>(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
bool_value: IntValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
bool_to_i8(&ctx.builder, ctx.ctx, bool_value)
|
||||
self.bool_to_int_type(ctx, bool_value, ctx.ctx.i8_type())
|
||||
}
|
||||
|
||||
/// See [`bool_to_int_type`].
|
||||
fn bool_to_int_type<'ctx>(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
bool_value: IntValue<'ctx>,
|
||||
ty: IntType<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
bool_to_int_type(&ctx.builder, bool_value, ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -933,7 +933,7 @@ pub fn gen_func_impl<
|
||||
let param_val = param.into_int_value();
|
||||
|
||||
if expected_ty.get_bit_width() == 8 && param_val.get_type().get_bit_width() == 1 {
|
||||
bool_to_i8(&builder, context, param_val)
|
||||
bool_to_int_type(&builder, param_val, context.i8_type())
|
||||
} else {
|
||||
param_val
|
||||
}
|
||||
@ -1103,43 +1103,29 @@ pub fn gen_func<'ctx, G: CodeGenerator>(
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts the value of a boolean-like value `bool_value` into an `i1`.
|
||||
fn bool_to_i1<'ctx>(builder: &Builder<'ctx>, bool_value: IntValue<'ctx>) -> IntValue<'ctx> {
|
||||
if bool_value.get_type().get_bit_width() == 1 {
|
||||
bool_value
|
||||
} else {
|
||||
builder
|
||||
.build_int_compare(
|
||||
IntPredicate::NE,
|
||||
bool_value,
|
||||
bool_value.get_type().const_zero(),
|
||||
"tobool",
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the value of a boolean-like value `bool_value` into an `i8`.
|
||||
fn bool_to_i8<'ctx>(
|
||||
/// Converts the value of a boolean-like value `value` into an arbitrary [`IntType`].
|
||||
///
|
||||
/// This has the same semantics as `(ty)(value != 0)` in C.
|
||||
///
|
||||
/// The returned value is guaranteed to either be `0` or `1`, except for `ty == i1` where only the
|
||||
/// least-significant bit would be guaranteed to be `0` or `1`.
|
||||
fn bool_to_int_type<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
ctx: &'ctx Context,
|
||||
bool_value: IntValue<'ctx>,
|
||||
value: IntValue<'ctx>,
|
||||
ty: IntType<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let value_bits = bool_value.get_type().get_bit_width();
|
||||
match value_bits {
|
||||
8 => bool_value,
|
||||
1 => builder.build_int_z_extend(bool_value, ctx.i8_type(), "frombool").unwrap(),
|
||||
_ => bool_to_i8(
|
||||
// i1 -> i1 : %value ; no-op
|
||||
// i1 -> i<N> : zext i1 %value to i<N> ; guaranteed to be 0 or 1 - see docs
|
||||
// i<M> -> i<N>: zext i1 (icmp eq i<M> %value, 0) to i<N> ; same as i<M> -> i1 -> i<N>
|
||||
match (value.get_type().get_bit_width(), ty.get_bit_width()) {
|
||||
(1, 1) => value,
|
||||
(1, _) => builder.build_int_z_extend(value, ty, "frombool").unwrap(),
|
||||
_ => bool_to_int_type(
|
||||
builder,
|
||||
ctx,
|
||||
builder
|
||||
.build_int_compare(
|
||||
IntPredicate::NE,
|
||||
bool_value,
|
||||
bool_value.get_type().const_zero(),
|
||||
"",
|
||||
)
|
||||
.build_int_compare(IntPredicate::NE, value, value.get_type().const_zero(), "tobool")
|
||||
.unwrap(),
|
||||
ty,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user