nac3artiq: refactor timeline functions
This commit is contained in:
parent
c5e731f16d
commit
c429a86586
|
@ -163,6 +163,108 @@ impl Nac3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ARTIQ timeline control with now-pinning optimization.
|
||||||
|
// This is a bit of mess due to endianness issues.
|
||||||
|
// Modify gateware to make `now` little-endian, since we don't have OpenRISC anymore?
|
||||||
|
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.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!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)))
|
||||||
|
),(
|
||||||
|
"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.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!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)))
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Nac3 {
|
impl Nac3 {
|
||||||
#[new]
|
#[new]
|
||||||
|
@ -173,107 +275,7 @@ impl Nac3 {
|
||||||
_ => return Err(exceptions::PyValueError::new_err("invalid ISA")),
|
_ => return Err(exceptions::PyValueError::new_err("invalid ISA")),
|
||||||
};
|
};
|
||||||
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
|
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
|
||||||
let mut builtins = vec![];
|
let builtins = if isa == Isa::RiscV { timeline_builtins(&primitive) } else { vec![] };
|
||||||
if isa == Isa::RiscV {
|
|
||||||
builtins.push((
|
|
||||||
"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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)))
|
|
||||||
));
|
|
||||||
builtins.push((
|
|
||||||
"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.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!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)))
|
|
||||||
));
|
|
||||||
builtins.push((
|
|
||||||
"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.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!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let (composer, builtins_def, builtins_ty) = TopLevelComposer::new(builtins);
|
let (composer, builtins_def, builtins_ty) = TopLevelComposer::new(builtins);
|
||||||
Ok(Nac3 {
|
Ok(Nac3 {
|
||||||
isa,
|
isa,
|
||||||
|
|
Loading…
Reference in New Issue