1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8#[allow(dead_code)]
12pub struct MemoryLayout {
13 pub type_name: String,
15 pub size: usize,
17 pub align: usize,
19}
20#[allow(dead_code)]
21impl MemoryLayout {
22 pub fn new(type_name: impl Into<String>, size: usize, align: usize) -> Self {
24 Self {
25 type_name: type_name.into(),
26 size,
27 align,
28 }
29 }
30 pub fn stride(&self) -> usize {
32 (self.size + self.align - 1) & !(self.align - 1)
33 }
34 pub fn is_valid(&self) -> bool {
36 self.align > 0 && self.align.is_power_of_two() && self.size <= self.stride()
37 }
38 pub fn align_offset(&self, offset: usize) -> usize {
40 let mask = self.align - 1;
41 (offset + mask) & !mask
42 }
43 pub fn describe(&self) -> String {
45 format!(
46 "{}: size={}, align={}, stride={}",
47 self.type_name,
48 self.size,
49 self.align,
50 self.stride()
51 )
52 }
53}
54#[allow(dead_code)]
56pub struct CStructLayout {
57 pub name: String,
59 pub fields: Vec<(String, usize, usize)>,
61}
62#[allow(dead_code)]
63impl CStructLayout {
64 pub fn new(name: impl Into<String>) -> Self {
66 Self {
67 name: name.into(),
68 fields: Vec::new(),
69 }
70 }
71 pub fn add_field(mut self, name: impl Into<String>, size: usize, align: usize) -> Self {
73 self.fields.push((name.into(), size, align));
74 self
75 }
76 pub fn field_offset(&self, idx: usize) -> usize {
78 let mut offset = 0usize;
79 for (i, (_, size, align)) in self.fields.iter().enumerate() {
80 let mask = align - 1;
81 offset = (offset + mask) & !mask;
82 if i == idx {
83 return offset;
84 }
85 offset += size;
86 }
87 offset
88 }
89 pub fn total_size(&self) -> usize {
91 if self.fields.is_empty() {
92 return 0;
93 }
94 let max_align = self.fields.iter().map(|(_, _, a)| *a).max().unwrap_or(1);
95 let mut offset = 0usize;
96 for (_, size, align) in &self.fields {
97 let mask = align - 1;
98 offset = (offset + mask) & !mask;
99 offset += size;
100 }
101 let mask = max_align - 1;
102 (offset + mask) & !mask
103 }
104 pub fn describe(&self) -> String {
106 let offsets: Vec<String> = (0..self.fields.len())
107 .map(|i| {
108 format!(
109 " [{}] {} @ offset {}",
110 i,
111 self.fields[i].0,
112 self.field_offset(i)
113 )
114 })
115 .collect();
116 format!(
117 "struct {} {{\n{}\n}} size={}",
118 self.name,
119 offsets.join("\n"),
120 self.total_size()
121 )
122 }
123}
124#[allow(dead_code)]
126pub enum PointerKind {
127 Raw,
129 Fat { metadata_size: usize },
131 Tagged { tag_bits: u32 },
133 VTable { num_methods: usize },
135}
136#[allow(dead_code)]
138pub struct PointerRepr {
139 pub kind: PointerKind,
141 pub addr_bytes: usize,
143}
144#[allow(dead_code)]
145impl PointerRepr {
146 pub fn raw64() -> Self {
148 Self {
149 kind: PointerKind::Raw,
150 addr_bytes: 8,
151 }
152 }
153 pub fn fat64(metadata_size: usize) -> Self {
155 Self {
156 kind: PointerKind::Fat { metadata_size },
157 addr_bytes: 8,
158 }
159 }
160 pub fn tagged(tag_bits: u32) -> Self {
162 Self {
163 kind: PointerKind::Tagged { tag_bits },
164 addr_bytes: 8,
165 }
166 }
167 pub fn total_size(&self) -> usize {
169 match &self.kind {
170 PointerKind::Raw => self.addr_bytes,
171 PointerKind::Fat { metadata_size } => self.addr_bytes + metadata_size,
172 PointerKind::Tagged { .. } => self.addr_bytes,
173 PointerKind::VTable { .. } => self.addr_bytes * 2,
174 }
175 }
176 pub fn describe(&self) -> String {
178 match &self.kind {
179 PointerKind::Raw => format!("*raw ({} bytes)", self.addr_bytes),
180 PointerKind::Fat { metadata_size } => {
181 format!(
182 "*fat (addr={} meta={} total={})",
183 self.addr_bytes,
184 metadata_size,
185 self.total_size()
186 )
187 }
188 PointerKind::Tagged { tag_bits } => {
189 format!("*tagged ({} tag bits, {} bytes)", tag_bits, self.addr_bytes)
190 }
191 PointerKind::VTable { num_methods } => {
192 format!(
193 "*dyn ({} methods, {} bytes)",
194 num_methods,
195 self.total_size()
196 )
197 }
198 }
199 }
200}
201#[allow(dead_code)]
203pub struct Ieee754Descriptor {
204 pub name: String,
206 pub total_bits: u32,
208 pub exponent_bits: u32,
210 pub mantissa_bits: u32,
212}
213#[allow(dead_code)]
214impl Ieee754Descriptor {
215 pub fn new(name: impl Into<String>, total: u32, exp: u32, mant: u32) -> Self {
217 Self {
218 name: name.into(),
219 total_bits: total,
220 exponent_bits: exp,
221 mantissa_bits: mant,
222 }
223 }
224 pub fn binary32() -> Self {
226 Self::new("binary32", 32, 8, 23)
227 }
228 pub fn binary64() -> Self {
230 Self::new("binary64", 64, 11, 52)
231 }
232 pub fn exponent_bias(&self) -> u32 {
234 (1u32 << (self.exponent_bits - 1)) - 1
235 }
236 pub fn max_exponent(&self) -> i32 {
238 self.exponent_bias() as i32
239 }
240 pub fn is_valid(&self) -> bool {
242 self.total_bits == 1 + self.exponent_bits + self.mantissa_bits
243 }
244 pub fn describe(&self) -> String {
246 format!(
247 "{}: total={} sign=1 exp={} mant={} bias={}",
248 self.name,
249 self.total_bits,
250 self.exponent_bits,
251 self.mantissa_bits,
252 self.exponent_bias()
253 )
254 }
255}
256#[allow(dead_code)]
258pub struct BitfieldDescriptor {
259 pub name: String,
261 pub offset: u32,
263 pub width: u32,
265}
266#[allow(dead_code)]
267impl BitfieldDescriptor {
268 pub fn new(name: impl Into<String>, offset: u32, width: u32) -> Self {
270 Self {
271 name: name.into(),
272 offset,
273 width,
274 }
275 }
276 pub fn mask(&self) -> u64 {
278 let raw = if self.width >= 64 {
279 !0u64
280 } else {
281 (1u64 << self.width) - 1
282 };
283 raw << self.offset
284 }
285 pub fn extract(&self, word: u64) -> u64 {
287 (word & self.mask()) >> self.offset
288 }
289 pub fn insert(&self, word: u64, value: u64) -> u64 {
291 let m = self.mask();
292 (word & !m) | ((value << self.offset) & m)
293 }
294 pub fn fits_in(&self, word_bits: u32) -> bool {
296 self.offset + self.width <= word_bits
297 }
298}
299#[allow(dead_code)]
301pub struct RegisterFileState {
302 pub regs: Vec<u64>,
304}
305#[allow(dead_code)]
306impl RegisterFileState {
307 pub fn new(count: usize) -> Self {
309 Self {
310 regs: vec![0u64; count],
311 }
312 }
313 pub fn read(&self, r: usize) -> Option<u64> {
315 self.regs.get(r).copied()
316 }
317 pub fn write(&mut self, r: usize, value: u64) {
319 if r < self.regs.len() {
320 self.regs[r] = value;
321 }
322 }
323 pub fn verify_raw(&mut self, r: usize, v: u64) -> bool {
325 self.write(r, v);
326 self.read(r) == Some(v)
327 }
328 pub fn count(&self) -> usize {
330 self.regs.len()
331 }
332 pub fn describe(&self) -> String {
334 let parts: Vec<String> = self
335 .regs
336 .iter()
337 .enumerate()
338 .map(|(i, v)| format!("r{}=0x{:x}", i, v))
339 .collect();
340 format!("[{}]", parts.join(", "))
341 }
342}