From c5e731f16dc9e46f1266fcf26aa936fc1102a971 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 2 Oct 2021 23:22:46 +0800 Subject: [PATCH] nac3artiq: implement timeline functions --- nac3artiq/src/lib.rs | 65 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 34a54c0b..a01009bf 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -5,6 +5,8 @@ use std::process::Command; use std::sync::Arc; use inkwell::{ + AddressSpace, + values::BasicValueEnum, passes::{PassManager, PassManagerBuilder}, targets::*, OptimizationLevel, @@ -181,8 +183,18 @@ impl Nac3 { vars: HashMap::new(), }, Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { - unimplemented!(); + |ctx, _, _, _| { + let i64_type = ctx.ctx.i64_type(); + let now = ctx.module.get_global("now").unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now")); + let now_raw = ctx.builder.build_load(now.as_pointer_value(), "now"); + if let BasicValueEnum::IntValue(now_raw) = now_raw { + let i64_32 = i64_type.const_int(32, false).into(); + let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now_shl"); + let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now_lshr").into(); + Some(ctx.builder.build_or(now_lo, now_hi, "now_or").into()) + } else { + unreachable!() + } } ))) )); @@ -198,8 +210,26 @@ impl Nac3 { vars: HashMap::new(), }, Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { - unimplemented!(); + |ctx, _, _, args| { + let i32_type = ctx.ctx.i64_type(); + let i64_type = ctx.ctx.i64_type(); + let i64_32 = i64_type.const_int(32, false).into(); + if let BasicValueEnum::IntValue(time) = args[0].1 { + let time_hi = ctx.builder.build_int_truncate(ctx.builder.build_right_shift(time, i64_32, false, "now_lshr"), i32_type, "now_trunc"); + let time_lo = ctx.builder.build_int_truncate(time, i32_type, "now_trunc"); + let now = ctx.module.get_global("now").unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now")); + let now_hiptr = ctx.builder.build_bitcast(now, i32_type.ptr_type(AddressSpace::Generic), "now_bitcast"); + if let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr { + let now_loptr = unsafe { ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false).into()], "now_gep") }; + ctx.builder.build_store(now_hiptr, time_hi); + ctx.builder.build_store(now_loptr, time_lo); + None + } else { + unreachable!(); + } + } else { + unreachable!(); + } } ))) )); @@ -215,8 +245,31 @@ impl Nac3 { vars: HashMap::new(), }, Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { - unimplemented!(); + |ctx, _, _, args| { + let i32_type = ctx.ctx.i64_type(); + let i64_type = ctx.ctx.i64_type(); + let i64_32 = i64_type.const_int(32, false).into(); + let now = ctx.module.get_global("now").unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now")); + let now_raw = ctx.builder.build_load(now.as_pointer_value(), "now"); + if let (BasicValueEnum::IntValue(now_raw), BasicValueEnum::IntValue(dt)) = (now_raw, args[0].1) { + let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now_shl"); + let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now_lshr").into(); + let now_val = ctx.builder.build_or(now_lo, now_hi, "now_or"); + let time = ctx.builder.build_int_add(now_val, dt, "now_add"); + let time_hi = ctx.builder.build_int_truncate(ctx.builder.build_right_shift(time, i64_32, false, "now_lshr"), i32_type, "now_trunc"); + let time_lo = ctx.builder.build_int_truncate(time, i32_type, "now_trunc"); + let now_hiptr = ctx.builder.build_bitcast(now, i32_type.ptr_type(AddressSpace::Generic), "now_bitcast"); + if let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr { + let now_loptr = unsafe { ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false).into()], "now_gep") }; + ctx.builder.build_store(now_hiptr, time_hi); + ctx.builder.build_store(now_loptr, time_lo); + None + } else { + unreachable!(); + } + } else { + unreachable!(); + } } ))) ));