From d3a21d75fa1b2250d81a4bcd10a225167283002c Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 8 Oct 2021 23:13:46 +0800 Subject: [PATCH] handle time cursor functions on the Rust side entirely This is preparation for with sequential/with parallel support. --- nac3artiq/artiq_builtins.py | 5 - nac3artiq/artiq_timeline_extern.py | 20 ---- nac3artiq/src/builtins.rs | 167 ----------------------------- nac3artiq/src/lib.rs | 57 ++++++++-- 4 files changed, 46 insertions(+), 203 deletions(-) delete mode 100644 nac3artiq/artiq_timeline_extern.py delete mode 100644 nac3artiq/src/builtins.rs diff --git a/nac3artiq/artiq_builtins.py b/nac3artiq/artiq_builtins.py index dc5c6eaa..886c334f 100644 --- a/nac3artiq/artiq_builtins.py +++ b/nac3artiq/artiq_builtins.py @@ -2,11 +2,6 @@ from numpy import int32, int64 from language import * - -import device_db -if device_db.device_db["core"]["arguments"]["target"] == "cortexa9": - from artiq_timeline_extern import * - @extern def rtio_init(): raise NotImplementedError("syscall not simulated") diff --git a/nac3artiq/artiq_timeline_extern.py b/nac3artiq/artiq_timeline_extern.py deleted file mode 100644 index fccf81ca..00000000 --- a/nac3artiq/artiq_timeline_extern.py +++ /dev/null @@ -1,20 +0,0 @@ -from numpy import int32, int64 -from language import * - - -__all__ = ["now_mu", "at_mu", "delay_mu"] - - -@extern -def now_mu() -> int64: - raise NotImplementedError("syscall not simulated") - - -@extern -def at_mu(t: int64): - raise NotImplementedError("syscall not simulated") - - -@extern -def delay_mu(dt: int64): - raise NotImplementedError("syscall not simulated") diff --git a/nac3artiq/src/builtins.rs b/nac3artiq/src/builtins.rs deleted file mode 100644 index a9cb4485..00000000 --- a/nac3artiq/src/builtins.rs +++ /dev/null @@ -1,167 +0,0 @@ -use inkwell::{values::BasicValueEnum, AddressSpace, AtomicOrdering}; -use nac3core::{ - toplevel::GenCall, - typecheck::{ - type_inferencer::PrimitiveStore, - typedef::{FunSignature, FuncArg}, - }, -}; -use rustpython_parser::ast::StrRef; -use std::{collections::HashMap, sync::Arc}; - -// ARTIQ timeline control with now-pinning optimization. -pub fn timeline_builtins(primitive: &PrimitiveStore) -> Vec<(StrRef, FunSignature, Arc)> { - vec![ - ( - "now_mu".into(), - FunSignature { - args: vec![], - ret: primitive.int64, - vars: HashMap::new(), - }, - Arc::new(GenCall::new(Box::new(|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!() - } - }))), - ), - ( - "at_mu".into(), - FunSignature { - args: vec![FuncArg { - name: "t".into(), - ty: primitive.int64, - default_value: None, - }], - ret: primitive.none, - vars: HashMap::new(), - }, - Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let i32_type = ctx.ctx.i32_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) - .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) - .unwrap(); - ctx.builder - .build_store(now_loptr, time_lo) - .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) - .unwrap(); - None - } else { - unreachable!(); - } - } else { - unreachable!(); - } - }))), - ), - ( - "delay_mu".into(), - FunSignature { - args: vec![FuncArg { - name: "dt".into(), - ty: primitive.int64, - default_value: None, - }], - ret: primitive.none, - vars: HashMap::new(), - }, - Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let i32_type = ctx.ctx.i32_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) - .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) - .unwrap(); - ctx.builder - .build_store(now_loptr, time_lo) - .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent) - .unwrap(); - None - } else { - unreachable!(); - } - } else { - unreachable!(); - } - }))), - ), - ] -} diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 813f7984..fb829af6 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -21,19 +21,18 @@ use parking_lot::{RwLock, Mutex}; use nac3core::{ codegen::{CodeGenTask, WithCall, WorkerRegistry}, symbol_resolver::SymbolResolver, - toplevel::{composer::TopLevelComposer, TopLevelContext, TopLevelDef}, - typecheck::typedef::FunSignature, -}; -use nac3core::{ - toplevel::DefinitionId, + toplevel::{composer::TopLevelComposer, TopLevelContext, TopLevelDef, DefinitionId, GenCall}, + typecheck::typedef::{FunSignature, FuncArg}, typecheck::{type_inferencer::PrimitiveStore, typedef::Type}, }; use crate::symbol_resolver::Resolver; -mod builtins; +mod timeline; mod symbol_resolver; +use timeline::TimeFns; + #[derive(PartialEq, Clone, Copy)] enum Isa { RiscV, @@ -186,12 +185,48 @@ impl Nac3 { "cortexa9" => Isa::CortexA9, _ => return Err(exceptions::PyValueError::new_err("invalid ISA")), }; - let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0; - let builtins = if isa == Isa::RiscV { - builtins::timeline_builtins(&primitive) - } else { - vec![] + let time_fns: &(dyn TimeFns + Sync) = match isa { + Isa::RiscV => &timeline::NOW_PINNING_TIME_FNS, + Isa::CortexA9 => &timeline::EXTERN_TIME_FNS, }; + let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0; + let builtins = vec![ + ( + "now_mu".into(), + FunSignature { + args: vec![], + ret: primitive.int64, + vars: HashMap::new(), + }, + Arc::new(GenCall::new(Box::new(move |ctx, _, _, _| Some(time_fns.emit_now_mu(ctx))))), + ), + ( + "at_mu".into(), + FunSignature { + args: vec![FuncArg { + name: "t".into(), + ty: primitive.int64, + default_value: None, + }], + ret: primitive.none, + vars: HashMap::new(), + }, + Arc::new(GenCall::new(Box::new(move |ctx, _, _, args| { time_fns.emit_at_mu(ctx, args[0].1); None }))), + ), + ( + "delay_mu".into(), + FunSignature { + args: vec![FuncArg { + name: "dt".into(), + ty: primitive.int64, + default_value: None, + }], + ret: primitive.none, + vars: HashMap::new(), + }, + Arc::new(GenCall::new(Box::new(move |ctx, _, _, args| { time_fns.emit_delay_mu(ctx, args[0].1); None }))), + ), + ]; let (composer, builtins_def, builtins_ty) = TopLevelComposer::new(builtins); let builtins_mod = PyModule::import(py, "builtins").unwrap();