cubecl_core/frontend/
asm.rs1use alloc::{string::String, vec::Vec};
2
3use cubecl_ir::{
4 Scope,
5 dialect::{InlineAsmOp, OperationPtrExt},
6 interfaces::TypeExt,
7};
8use pliron::{op::Op, r#type::Typed, value::Value};
9
10use crate::frontend::{HasValue, assign};
11
12#[derive(Default)]
13pub struct BuildAsmExpand {
14 asm: String,
15 out_values: Vec<Value>,
16 in_values: Vec<Value>,
17 pure: bool,
18 nomem: bool,
19 readonly: bool,
20}
21
22impl BuildAsmExpand {
23 pub fn new(asm: String) -> Self {
24 BuildAsmExpand {
25 asm,
26 ..Default::default()
27 }
28 }
29
30 pub fn push_output<T: HasValue>(mut self, scope: &Scope, output: &T) -> Self {
34 let value = output.value(scope);
35 self.out_values.push(value);
36 self
37 }
38
39 pub fn push_input<T: HasValue>(mut self, scope: &Scope, input: T) -> Self {
40 let value = input.value(scope);
41 self.in_values.push(value);
42 self
43 }
44
45 pub fn pure(mut self) -> Self {
46 self.pure = true;
47 self
48 }
49
50 pub fn nomem(mut self) -> Self {
51 self.nomem = true;
52 self
53 }
54
55 pub fn readonly(mut self) -> Self {
56 self.readonly = true;
57 self
58 }
59
60 pub fn register(self, scope: &Scope) {
61 let ctx = scope.ctx_mut();
62 let result_types = self
63 .out_values
64 .iter()
65 .map(|it| it.get_type(ctx).as_ptr(ctx).inner)
66 .collect();
67 let op = InlineAsmOp::new(ctx, result_types, self.asm, self.in_values);
68 if self.pure {
69 op.set_pure(ctx);
70 }
71 if self.nomem {
72 op.set_nomem(ctx);
73 }
74 if self.readonly {
75 op.set_readonly(ctx);
76 }
77 scope.register(&op);
78 for (&out_ptr, result) in self.out_values.iter().zip(op.get_operation().results(ctx)) {
80 assign::expand_element(scope, result.into(), out_ptr.into());
81 }
82 }
83}