[core] codegen: Add function to get format constants for integers

This commit is contained in:
David Mak 2024-08-12 17:54:01 +08:00
parent 3aab6e01bb
commit f4d785a65f
1 changed files with 31 additions and 1 deletions

View File

@ -19,7 +19,7 @@ use inkwell::{
module::Module,
passes::PassBuilderOptions,
targets::{CodeModel, RelocMode, Target, TargetMachine, TargetTriple},
types::{AnyType, BasicType, BasicTypeEnum},
types::{AnyType, BasicType, BasicTypeEnum, IntType},
values::{BasicValueEnum, FunctionValue, IntValue, PhiValue, PointerValue},
AddressSpace, IntPredicate, OptimizationLevel,
};
@ -1094,6 +1094,36 @@ fn gen_in_range_check<'ctx>(
ctx.builder.build_int_compare(IntPredicate::SLT, lo, hi, "cmp").unwrap()
}
/// Returns the `fprintf` format constant for the given [`llvm_int_t`][`IntType`] on a platform with
/// [`llvm_usize`] as its native word size.
///
/// Note that, similar to format constants in `<inttypes.h>`, these constants need to be prepended
/// with `%`.
#[must_use]
pub fn get_fprintf_format_constant<'ctx>(
llvm_usize: IntType<'ctx>,
llvm_int_t: IntType<'ctx>,
is_unsigned: bool,
) -> String {
debug_assert!(matches!(llvm_usize.get_bit_width(), 8 | 16 | 32 | 64));
let conv_spec = if is_unsigned { 'u' } else { 'd' };
// https://en.cppreference.com/w/c/language/arithmetic_types
// Note that NAC3 does **not** support LP32 and LLP64 configurations
match llvm_int_t.get_bit_width() {
8 => format!("hh{conv_spec}"),
16 => format!("h{conv_spec}"),
32 => conv_spec.to_string(),
64 => format!("{}{conv_spec}", if llvm_usize.get_bit_width() == 64 { "l" } else { "ll" }),
_ => todo!(
"Not yet implemented for i{} on {}-bit platform",
llvm_int_t.get_bit_width(),
llvm_usize.get_bit_width()
),
}
}
/// Returns the internal name for the `va_count` argument, used to indicate the number of arguments
/// passed to the variadic function.
fn get_va_count_arg_name(arg_name: StrRef) -> StrRef {