forked from M-Labs/nac3
handle time cursor functions on the Rust side entirely
This is preparation for with sequential/with parallel support.
This commit is contained in:
parent
a07674a042
commit
d3a21d75fa
|
@ -2,11 +2,6 @@ from numpy import int32, int64
|
||||||
|
|
||||||
from language import *
|
from language import *
|
||||||
|
|
||||||
|
|
||||||
import device_db
|
|
||||||
if device_db.device_db["core"]["arguments"]["target"] == "cortexa9":
|
|
||||||
from artiq_timeline_extern import *
|
|
||||||
|
|
||||||
@extern
|
@extern
|
||||||
def rtio_init():
|
def rtio_init():
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
|
@ -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")
|
|
|
@ -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<GenCall>)> {
|
|
||||||
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!();
|
|
||||||
}
|
|
||||||
}))),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -21,19 +21,18 @@ use parking_lot::{RwLock, Mutex};
|
||||||
use nac3core::{
|
use nac3core::{
|
||||||
codegen::{CodeGenTask, WithCall, WorkerRegistry},
|
codegen::{CodeGenTask, WithCall, WorkerRegistry},
|
||||||
symbol_resolver::SymbolResolver,
|
symbol_resolver::SymbolResolver,
|
||||||
toplevel::{composer::TopLevelComposer, TopLevelContext, TopLevelDef},
|
toplevel::{composer::TopLevelComposer, TopLevelContext, TopLevelDef, DefinitionId, GenCall},
|
||||||
typecheck::typedef::FunSignature,
|
typecheck::typedef::{FunSignature, FuncArg},
|
||||||
};
|
|
||||||
use nac3core::{
|
|
||||||
toplevel::DefinitionId,
|
|
||||||
typecheck::{type_inferencer::PrimitiveStore, typedef::Type},
|
typecheck::{type_inferencer::PrimitiveStore, typedef::Type},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::symbol_resolver::Resolver;
|
use crate::symbol_resolver::Resolver;
|
||||||
|
|
||||||
mod builtins;
|
mod timeline;
|
||||||
mod symbol_resolver;
|
mod symbol_resolver;
|
||||||
|
|
||||||
|
use timeline::TimeFns;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
enum Isa {
|
enum Isa {
|
||||||
RiscV,
|
RiscV,
|
||||||
|
@ -186,12 +185,48 @@ impl Nac3 {
|
||||||
"cortexa9" => Isa::CortexA9,
|
"cortexa9" => Isa::CortexA9,
|
||||||
_ => return Err(exceptions::PyValueError::new_err("invalid ISA")),
|
_ => return Err(exceptions::PyValueError::new_err("invalid ISA")),
|
||||||
};
|
};
|
||||||
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
|
let time_fns: &(dyn TimeFns + Sync) = match isa {
|
||||||
let builtins = if isa == Isa::RiscV {
|
Isa::RiscV => &timeline::NOW_PINNING_TIME_FNS,
|
||||||
builtins::timeline_builtins(&primitive)
|
Isa::CortexA9 => &timeline::EXTERN_TIME_FNS,
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
};
|
};
|
||||||
|
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 (composer, builtins_def, builtins_ty) = TopLevelComposer::new(builtins);
|
||||||
|
|
||||||
let builtins_mod = PyModule::import(py, "builtins").unwrap();
|
let builtins_mod = PyModule::import(py, "builtins").unwrap();
|
||||||
|
|
Loading…
Reference in New Issue