sp1_recursion_compiler/ir/
ptr.rs1use core::ops::{Add, Sub};
2
3use p3_field::Field;
4
5use super::{Builder, Config, DslIr, MemIndex, MemVariable, SymbolicVar, Usize, Var, Variable};
6
7#[derive(Debug, Clone, Copy)]
9pub struct Ptr<N> {
10 pub address: Var<N>,
11}
12
13pub struct SymbolicPtr<N: Field> {
14 pub address: SymbolicVar<N>,
15}
16
17impl<C: Config> Builder<C> {
18 pub(crate) fn alloc(&mut self, len: Usize<C::N>, size: usize) -> Ptr<C::N> {
20 let ptr = Ptr::uninit(self);
21 self.push_op(DslIr::Alloc(ptr, len, size));
22 ptr
23 }
24
25 pub fn load<V: MemVariable<C>>(&mut self, var: V, ptr: Ptr<C::N>, index: MemIndex<C::N>) {
27 var.load(ptr, index, self);
28 }
29
30 pub fn store<V: MemVariable<C>>(&mut self, ptr: Ptr<C::N>, index: MemIndex<C::N>, value: V) {
32 value.store(ptr, index, self);
33 }
34}
35
36impl<C: Config> Variable<C> for Ptr<C::N> {
37 type Expression = SymbolicPtr<C::N>;
38
39 fn uninit(builder: &mut Builder<C>) -> Self {
40 Ptr { address: Var::uninit(builder) }
41 }
42
43 fn assign(&self, src: Self::Expression, builder: &mut Builder<C>) {
44 self.address.assign(src.address, builder);
45 }
46
47 fn assert_eq(
48 lhs: impl Into<Self::Expression>,
49 rhs: impl Into<Self::Expression>,
50 builder: &mut Builder<C>,
51 ) {
52 Var::assert_eq(lhs.into().address, rhs.into().address, builder);
53 }
54
55 fn assert_ne(
56 lhs: impl Into<Self::Expression>,
57 rhs: impl Into<Self::Expression>,
58 builder: &mut Builder<C>,
59 ) {
60 Var::assert_ne(lhs.into().address, rhs.into().address, builder);
61 }
62}
63
64impl<C: Config> MemVariable<C> for Ptr<C::N> {
65 fn size_of() -> usize {
66 1
67 }
68
69 fn load(&self, ptr: Ptr<C::N>, index: MemIndex<C::N>, builder: &mut Builder<C>) {
70 self.address.load(ptr, index, builder);
71 }
72
73 fn store(&self, ptr: Ptr<<C as Config>::N>, index: MemIndex<C::N>, builder: &mut Builder<C>) {
74 self.address.store(ptr, index, builder);
75 }
76}
77
78impl<N: Field> From<Ptr<N>> for SymbolicPtr<N> {
79 fn from(ptr: Ptr<N>) -> Self {
80 SymbolicPtr { address: SymbolicVar::from(ptr.address) }
81 }
82}
83
84impl<N: Field> Add for Ptr<N> {
85 type Output = SymbolicPtr<N>;
86
87 fn add(self, rhs: Self) -> Self::Output {
88 SymbolicPtr { address: self.address + rhs.address }
89 }
90}
91
92impl<N: Field> Sub for Ptr<N> {
93 type Output = SymbolicPtr<N>;
94
95 fn sub(self, rhs: Self) -> Self::Output {
96 SymbolicPtr { address: self.address - rhs.address }
97 }
98}
99
100impl<N: Field> Add for SymbolicPtr<N> {
101 type Output = Self;
102
103 fn add(self, rhs: Self) -> Self {
104 Self { address: self.address + rhs.address }
105 }
106}
107
108impl<N: Field> Sub for SymbolicPtr<N> {
109 type Output = Self;
110
111 fn sub(self, rhs: Self) -> Self {
112 Self { address: self.address - rhs.address }
113 }
114}
115
116impl<N: Field> Add<Ptr<N>> for SymbolicPtr<N> {
117 type Output = Self;
118
119 fn add(self, rhs: Ptr<N>) -> Self {
120 Self { address: self.address + rhs.address }
121 }
122}
123
124impl<N: Field> Sub<Ptr<N>> for SymbolicPtr<N> {
125 type Output = Self;
126
127 fn sub(self, rhs: Ptr<N>) -> Self {
128 Self { address: self.address - rhs.address }
129 }
130}
131
132impl<N: Field> Add<SymbolicPtr<N>> for Ptr<N> {
133 type Output = SymbolicPtr<N>;
134
135 fn add(self, rhs: SymbolicPtr<N>) -> SymbolicPtr<N> {
136 SymbolicPtr { address: self.address + rhs.address }
137 }
138}
139
140impl<N: Field> Add<SymbolicVar<N>> for Ptr<N> {
141 type Output = SymbolicPtr<N>;
142
143 fn add(self, rhs: SymbolicVar<N>) -> SymbolicPtr<N> {
144 SymbolicPtr { address: self.address + rhs }
145 }
146}
147
148impl<N: Field> Sub<SymbolicVar<N>> for Ptr<N> {
149 type Output = SymbolicPtr<N>;
150
151 fn sub(self, rhs: SymbolicVar<N>) -> SymbolicPtr<N> {
152 SymbolicPtr { address: self.address - rhs }
153 }
154}
155
156impl<N: Field> Sub<SymbolicPtr<N>> for Ptr<N> {
157 type Output = SymbolicPtr<N>;
158
159 fn sub(self, rhs: SymbolicPtr<N>) -> SymbolicPtr<N> {
160 SymbolicPtr { address: self.address - rhs.address }
161 }
162}
163
164impl<N: Field> Add<Usize<N>> for Ptr<N> {
165 type Output = SymbolicPtr<N>;
166
167 fn add(self, rhs: Usize<N>) -> SymbolicPtr<N> {
168 match rhs {
169 Usize::Const(rhs) => {
170 SymbolicPtr { address: self.address + N::from_canonical_usize(rhs) }
171 }
172 Usize::Var(rhs) => SymbolicPtr { address: self.address + rhs },
173 }
174 }
175}
176
177impl<N: Field> Add<Usize<N>> for SymbolicPtr<N> {
178 type Output = SymbolicPtr<N>;
179
180 fn add(self, rhs: Usize<N>) -> SymbolicPtr<N> {
181 match rhs {
182 Usize::Const(rhs) => {
183 SymbolicPtr { address: self.address + N::from_canonical_usize(rhs) }
184 }
185 Usize::Var(rhs) => SymbolicPtr { address: self.address + rhs },
186 }
187 }
188}
189
190impl<N: Field> Sub<Usize<N>> for Ptr<N> {
191 type Output = SymbolicPtr<N>;
192
193 fn sub(self, rhs: Usize<N>) -> SymbolicPtr<N> {
194 match rhs {
195 Usize::Const(rhs) => {
196 SymbolicPtr { address: self.address - N::from_canonical_usize(rhs) }
197 }
198 Usize::Var(rhs) => SymbolicPtr { address: self.address - rhs },
199 }
200 }
201}
202
203impl<N: Field> Sub<Usize<N>> for SymbolicPtr<N> {
204 type Output = SymbolicPtr<N>;
205
206 fn sub(self, rhs: Usize<N>) -> SymbolicPtr<N> {
207 match rhs {
208 Usize::Const(rhs) => {
209 SymbolicPtr { address: self.address - N::from_canonical_usize(rhs) }
210 }
211 Usize::Var(rhs) => SymbolicPtr { address: self.address - rhs },
212 }
213 }
214}