1pub mod arg;
2mod dop_macro;
3pub mod field;
4pub mod fmt;
5mod opcode;
6pub mod pbs_macro;
7
8use lazy_static::lazy_static;
9use std::collections::HashMap;
10
11use crate::{dop, impl_dop, impl_dop_parser};
12pub use arg::{FromAsm, IsFlush, ParsingError, ToAsm, ToFlush};
13pub use field::{
14 ImmId, MemId, MulFactor, PbsGid, PeArithInsn, PeArithMsgInsn, PeMemInsn, PePbsInsn, PeSyncInsn,
15 RegId, SyncId,
16};
17pub use fmt::{
18 DOpRawHex, DOpRepr, PeArithHex, PeArithMsgHex, PeMemHex, PePbsHex, PeSyncHex, ToHex,
19};
20pub use opcode::{DOpType, Opcode};
21
22dop!(
23 ["ADD", opcode::Opcode::ADD(), PeArithInsn],
25 ["SUB", opcode::Opcode::SUB(), PeArithInsn],
26 ["MAC", opcode::Opcode::MAC(), PeArithInsn{mul_factor}],
27
28 ["ADDS", opcode::Opcode::ADDS(), PeArithMsgInsn],
30 ["SUBS", opcode::Opcode::SUBS(), PeArithMsgInsn],
31 ["SSUB", opcode::Opcode::SSUB(), PeArithMsgInsn],
32 ["MULS", opcode::Opcode::MULS(), PeArithMsgInsn],
33
34 ["LD", opcode::Opcode::LD(), PeMemInsn{ld}],
36 ["ST", opcode::Opcode::ST(), PeMemInsn{st}]
37
38 ["PBS", opcode::Opcode::PBS(1), PePbsInsn, "_F"],
40 ["PBS_ML2", opcode::Opcode::PBS(2), PePbsInsn, "_F"],
41 ["PBS_ML4", opcode::Opcode::PBS(4), PePbsInsn, "_F"],
42 ["PBS_ML8", opcode::Opcode::PBS(8), PePbsInsn, "_F"],
43
44 ["PBS_F", opcode::Opcode::PBS_F(1), PePbsInsn],
46 ["PBS_ML2_F", opcode::Opcode::PBS_F(2), PePbsInsn],
47 ["PBS_ML4_F", opcode::Opcode::PBS_F(4), PePbsInsn],
48 ["PBS_ML8_F", opcode::Opcode::PBS_F(8), PePbsInsn],
49
50 ["SYNC", opcode::Opcode::SYNC(), PeSyncInsn],
52);
53
54#[derive(Debug, Clone, Copy)]
55pub struct DigitParameters {
56 pub msg_w: usize,
57 pub carry_w: usize,
58}
59
60impl DigitParameters {
61 pub fn msg_mask(&self) -> usize {
63 (1 << self.msg_w) - 1
64 }
65 pub fn carry_mask(&self) -> usize {
67 ((1 << (self.carry_w)) - 1) << self.msg_w
68 }
69 pub fn padding_mask(&self) -> usize {
71 1 << (self.carry_w + self.msg_w)
72 }
73
74 pub fn data_mask(&self) -> usize {
76 self.carry_mask() | self.msg_mask()
77 }
78 pub fn raw_mask(&self) -> usize {
80 self.padding_mask() | self.data_mask()
81 }
82
83 pub fn msg_range(&self) -> usize {
85 1 << self.msg_w
86 }
87
88 pub fn nu(&self) -> usize {
91 (self.carry_mask() + self.msg_mask()) / self.msg_mask()
92 }
93
94 pub fn total_width(&self) -> usize {
95 self.msg_w + self.carry_w
96 }
97}
98
99#[enum_dispatch]
102pub trait PbsLut {
103 fn name(&self) -> &'static str;
104 fn gid(&self) -> PbsGid;
105 fn lut_nb(&self) -> u8;
106 fn lut_lg(&self) -> u8;
107 fn fn_at(&self, pos: usize, params: &DigitParameters, val: usize) -> usize;
108 fn deg_at(&self, pos: usize, params: &DigitParameters, deg: usize) -> usize;
109 fn lut_msk(&self) -> usize {
111 usize::MAX << self.lut_lg()
112 }
113}
114
115use crate::{impl_pbs, pbs};
116use enum_dispatch::enum_dispatch;
117use pbs_macro::{CMP_EQUAL, CMP_INFERIOR, CMP_SUPERIOR};
118
119pbs!(
120["None" => 0 [
121 @0 =>{
122 |_params: &DigitParameters, val | val;
123 |_params: &DigitParameters, deg| deg;
124 }
125]],
126["MsgOnly" => 1 [
127 @0 =>{
128 |params: &DigitParameters, val | val & params.msg_mask();
129 |params: &DigitParameters, _deg| params.msg_mask();
130 }
131]],
132["CarryOnly" => 2 [
133 @0 =>{
134 |params: &DigitParameters, val | val & params.carry_mask();
135 |params: &DigitParameters, _deg| params.carry_mask();
136 }
137]],
138["CarryInMsg" => 3 [
139 @0 =>{
140 |params: &DigitParameters, val | (val & params.carry_mask()) >> params.msg_w;
141 |params: &DigitParameters, _deg| params.msg_mask();
142 }
143]]
144["MultCarryMsg" => 4 [
145 @0 =>{
146 |params: &DigitParameters, val | (((val & params.carry_mask()) >> params.msg_w) * (val & params.msg_mask())) & params.data_mask();
147 |params: &DigitParameters, _deg| params.data_mask();
148 }
149]],
150["MultCarryMsgLsb" => 5 [
151 @0 =>{
152 |params: &DigitParameters, val | (((val & params.carry_mask()) >> params.msg_w) * (val & params.msg_mask())) & params.msg_mask();
153 |params: &DigitParameters, _deg| params.msg_mask();
154 },
155]],
156["MultCarryMsgMsb" => 6 [
157 @0 =>{
158 |params: &DigitParameters, val | ((((val & params.carry_mask()) >> params.msg_w) * (val & params.msg_mask())) >> params.msg_w) & params.msg_mask();
159 |params: &DigitParameters, _deg| params.msg_mask();
160 }
161]],
162["BwAnd" => 7 [
163 @0 =>{
164 |params: &DigitParameters, val | (((val & params.carry_mask()) >> params.msg_w) & (val & params.msg_mask())) & params.msg_mask();
165 |params: &DigitParameters, _deg| params.msg_mask();
166 }
167]],
168["BwOr" => 8 [
169 @0 =>{
170 |params: &DigitParameters, val | (((val & params.carry_mask()) >> params.msg_w) | (val & params.msg_mask())) & params.msg_mask();
171 |params: &DigitParameters, _deg| params.msg_mask();
172 }
173]],
174["BwXor" => 9 [
175 @0 =>{
176 |params: &DigitParameters, val | (((val & params.carry_mask()) >> params.msg_w) ^ (val & params.msg_mask())) & params.msg_mask();
177 |params: &DigitParameters, _deg| params.msg_mask();
178 }
179]],
180
181["CmpSign" => 10 [
182 @0 =>{
183 |_params: &DigitParameters, val | {
184 if val != 0 {1} else {0}
190 };
191 |_params: &DigitParameters, _deg| 1;
197 }
198]],
199["CmpReduce" => 11 [
200 @0 =>{
201 |params: &DigitParameters, val | {
202 let carry_field = (val & params.carry_mask()) >> params.msg_w;
209 let msg_field = val & params.msg_mask();
210
211 match (carry_field, msg_field) {
212 (CMP_EQUAL, lsb_cmp) => lsb_cmp,
213 _ => carry_field
214 }
215 };
216 |_params: &DigitParameters, _deg| 2;
217 }
218]]
219
220["CmpGt" => 12 [
221 @0 =>{
222 |params: &DigitParameters, val | match val & params.msg_mask() {
223 CMP_SUPERIOR => 1,
224 _ => 0,
225 };
226 |_params: &DigitParameters, _deg| 1;
227 }
228]],
229["CmpGte" => 13 [
230 @0 =>{
231 |params: &DigitParameters, val | match val & params.msg_mask() {
232 CMP_SUPERIOR | CMP_EQUAL => 1,
233 _ => 0,
234 };
235 |_params: &DigitParameters, _deg| 1;
236 }
237]],
238["CmpLt" => 14 [
240 @0 =>{
241 |params: &DigitParameters, val | match val & params.msg_mask() {
242 CMP_INFERIOR => 1,
243 _ => 0,
244 };
245 |_params: &DigitParameters, _deg| 1;
246 }
247]],
248["CmpLte" => 15 [
249 @0 =>{
250 |params: &DigitParameters, val | match val & params.msg_mask() {
251 CMP_INFERIOR | CMP_EQUAL => 1,
252 _ => 0,
253 };
254 |_params: &DigitParameters, _deg| 1;
255 }
256]],
257["CmpEq" => 16 [
258 @0 =>{
259 |params: &DigitParameters, val | match val & params.msg_mask() {
260 CMP_EQUAL => 1,
261 _ => 0,
262 };
263 |_params: &DigitParameters, _deg| 1;
264 }
265]],
266["CmpNeq" => 17 [
267 @0 =>{
268 |params: &DigitParameters, val | match val & params.msg_mask() {
269 CMP_EQUAL => 0,
270 _ => 1,
271 };
272 |_params: &DigitParameters, _deg| 1;
273 }
274]],
275["ManyGenProp" => 18 [ @0 =>{
277 |params: &DigitParameters, val| {
278 ((val & params.carry_mask()) >> (params.msg_w)) << 1| (((val & params.msg_mask()) == params.msg_mask()) as usize) };
281 |_params: &DigitParameters, _deg| 3;
282 },
283 @1 =>{
284 |params: &DigitParameters, val| { val & params.msg_mask()};
285 |params: &DigitParameters, _deg| params.msg_mask();
286 }
287]],
288["ReduceCarry2" => 19 [ @0 =>{
291 |_params: &DigitParameters, val | {
292 let carry = val >> 2;
293 let prop = (val & 3 == 3) as usize;
294 (carry << 1) | prop
295 };
296 |_params: &DigitParameters, _deg| 3;
297 }
298]],
299["ReduceCarry3" => 20 [ @0 =>{
302 |_params: &DigitParameters, val | {
303 let carry = val >> 3;
304 let prop = (val & 7 == 7) as usize;
305 (carry << 1) | prop
306 };
307 |_params: &DigitParameters, _deg| 3;
308 }
309]],
310["ReduceCarryPad" => 21 [ @0 =>{
320 |params: &DigitParameters, val | {
321 if val == params.data_mask() {
322 0
323 } else {
324 params.raw_mask()
325 }
326 };
327 |_params: &DigitParameters, _deg| 1;
328 }
329]],
330["GenPropAdd" => 22 [ @0 =>{
332 |params: &DigitParameters, val | {
333 let lhs = val & params.msg_mask();
334 let rhs = (val & params.carry_mask()) >> params.msg_w;
335 let rhs_gen = rhs >> 1;
336 (lhs + rhs_gen) & params.msg_mask()
337 };
338 |params: &DigitParameters, _deg| params.msg_mask();
339 }
340]],
341
342["IfTrueZeroed" => 23 [ @0 =>{
344 |params: &DigitParameters, val | {
345 let value = val & params.msg_mask();
346 let cond = (val & params.carry_mask()) >> params.msg_w;
347 if cond != 0 {0} else {value}
348 };
349 |params: &DigitParameters, _deg| params.msg_mask();
350 }
351]],
352["IfFalseZeroed" => 24 [ @0 =>{
354 |params: &DigitParameters, val | {
355 let value = val & params.msg_mask();
356 let cond = (val & params.carry_mask()) >> params.msg_w;
357 if cond != 0 {value} else {0}
358 };
359 |params: &DigitParameters, _deg| params.msg_mask();
360 }
361]],
362["Ripple2GenProp" => 25 [ @0 =>{
364 |params: &DigitParameters, val | {
365 (val & params.msg_mask()) * 2
366 };
367 |params: &DigitParameters, _deg| params.msg_mask();
368 }
369]],
370
371["TestMany2" => 128 [
373 @0 =>{
374 |_params: &DigitParameters, val | val;
375 |params: &DigitParameters, _deg| params.msg_mask();
376 },
377 @1 =>{
378 |_params: &DigitParameters, val | val +1;
379 |params: &DigitParameters, _deg| params.msg_mask();
380 },
381]],
382["TestMany4" => 129 [
383 @0 =>{
384 |_params: &DigitParameters, val | val;
385 |params: &DigitParameters, _deg| params.msg_mask();
386 },
387 @1 =>{
388 |_params: &DigitParameters, val | val +1;
389 |params: &DigitParameters, _deg| params.msg_mask();
390 },
391 @2 =>{
392 |_params: &DigitParameters, val | val +2;
393 |params: &DigitParameters, _deg| params.msg_mask();
394 },
395 @3 =>{
396 |_params: &DigitParameters, val | val +3;
397 |params: &DigitParameters, _deg| params.msg_mask();
398 },
399]],
400["TestMany8" => 130 [
401 @0 =>{
402 |_params: &DigitParameters, val | val;
403 |params: &DigitParameters, _deg| params.msg_mask();
404 },
405 @1 =>{
406 |_params: &DigitParameters, val | val +1;
407 |params: &DigitParameters, _deg| params.msg_mask();
408 },
409 @2 =>{
410 |_params: &DigitParameters, val | val +2;
411 |params: &DigitParameters, _deg| params.msg_mask();
412 },
413 @3 =>{
414 |_params: &DigitParameters, val | val +3;
415 |params: &DigitParameters, _deg| params.msg_mask();
416 },
417 @4 =>{
418 |_params: &DigitParameters, val | val +4;
419 |params: &DigitParameters, _deg| params.msg_mask();
420 },
421 @5 =>{
422 |_params: &DigitParameters, val | val +5;
423 |params: &DigitParameters, _deg| params.msg_mask();
424 },
425 @6 =>{
426 |_params: &DigitParameters, val | val +6;
427 |params: &DigitParameters, _deg| params.msg_mask();
428 },
429 @7 =>{
430 |_params: &DigitParameters, val | val +7;
431 |params: &DigitParameters, _deg| params.msg_mask();
432 },
433]],
434["ManyCarryMsg" => 26 [ @0 =>{
436 |params: &DigitParameters, val| { val & params.msg_mask()};
437 |params: &DigitParameters, _deg| params.msg_mask();
438 },
439 @1 =>{
440 |params: &DigitParameters, val| { val >> params.msg_w };
441 |params: &DigitParameters, _deg| (1 << (params.carry_w - 1)) - 1;
442 }
443]],
444["CmpGtMrg" => 27 [
445 @0 =>{
446 |params: &DigitParameters, val | {
447 let carry_field = (val & params.carry_mask()) >> params.msg_w;
448 let msg_field = val & params.msg_mask();
449
450 match (carry_field, msg_field) {
451 (CMP_SUPERIOR, _) |
452 (CMP_EQUAL, CMP_SUPERIOR) => 1,
453 _ => 0,
454 }
455 };
456 |_params: &DigitParameters, _deg| 1;
457 }
458]],
459["CmpGteMrg" => 28 [
460 @0 =>{
461 |params: &DigitParameters, val | {
462 let carry_field = (val & params.carry_mask()) >> params.msg_w;
463 let msg_field = val & params.msg_mask();
464
465 match (carry_field, msg_field) {
466 (CMP_SUPERIOR, _) |
467 (CMP_EQUAL, CMP_SUPERIOR) |
468 (CMP_EQUAL, CMP_EQUAL) => 1,
469 _ => 0,
470 }
471 };
472 |_params: &DigitParameters, _deg| 1;
473 }
474]],
475["CmpLtMrg" => 29 [
476 @0 =>{
477 |params: &DigitParameters, val | {
478 let carry_field = (val & params.carry_mask()) >> params.msg_w;
479 let msg_field = val & params.msg_mask();
480
481 match (carry_field, msg_field) {
482 (CMP_INFERIOR, _) |
483 (CMP_EQUAL, CMP_INFERIOR) => 1,
484 _ => 0,
485 }
486 };
487 |_params: &DigitParameters, _deg| 1;
488 }
489]],
490["CmpLteMrg" => 30 [
491 @0 =>{
492 |params: &DigitParameters, val | {
493 let carry_field = (val & params.carry_mask()) >> params.msg_w;
494 let msg_field = val & params.msg_mask();
495
496 match (carry_field, msg_field) {
497 (CMP_INFERIOR, _) |
498 (CMP_EQUAL, CMP_INFERIOR) |
499 (CMP_EQUAL, CMP_EQUAL) => 1,
500 _ => 0,
501 }
502 };
503 |_params: &DigitParameters, _deg| 1;
504 }
505]],
506["CmpEqMrg" => 31 [
507 @0 =>{
508 |params: &DigitParameters, val | {
509 let carry_field = (val & params.carry_mask()) >> params.msg_w;
510 let msg_field = val & params.msg_mask();
511
512 match (carry_field, msg_field) {
513 (CMP_EQUAL, CMP_EQUAL) => 1,
514 _ => 0,
515 }
516 };
517 |_params: &DigitParameters, _deg| 1;
518 }
519]],
520["CmpNeqMrg" => 32 [
521 @0 =>{
522 |params: &DigitParameters, val | {
523 let carry_field = (val & params.carry_mask()) >> params.msg_w;
524 let msg_field = val & params.msg_mask();
525
526 match (carry_field, msg_field) {
527 (CMP_EQUAL, CMP_EQUAL) => 0,
528 _ => 1,
529 }
530 };
531 |_params: &DigitParameters, _deg| 1;
532 }
533]],
534["IsSome" => 33 [
535 @0 =>{
536 |_params: &DigitParameters, val | {
537 if val != 0 { 1 } else { 0 }
538 };
539 |_params: &DigitParameters, _deg| 1;
540 }
541]],
542["CarryIsSome" => 34 [
543 @0 =>{
544 |params: &DigitParameters, val | {
545 let carry_field = (val & params.carry_mask()) >> params.msg_w;
546 if carry_field != 0 { 1 } else { 0 }
547 };
548 |_params: &DigitParameters, _deg| 1;
549 }
550]],
551["CarryIsNone" => 35 [
552 @0 =>{
553 |params: &DigitParameters, val | {
554 let carry_field = (val & params.carry_mask()) >> params.msg_w;
555 if carry_field == 0 { 1 } else { 0 }
556 };
557 |_params: &DigitParameters, _deg| 1;
558 }
559]],
560["MultCarryMsgIsSome" => 36 [
561 @0 =>{
562 |params: &DigitParameters, val | {
563 let carry_x_msg = (((val & params.carry_mask()) >> params.msg_w) * (val & params.msg_mask())) & params.data_mask();
564 if carry_x_msg != 0 { 1 } else { 0 }
565 };
566 |_params: &DigitParameters, _deg| 1;
567 }
568]],
569["MultCarryMsgMsbIsSome" => 37 [
570 @0 =>{
571 |params: &DigitParameters, val | {
572 let mul_msb = ((((val & params.carry_mask()) >> params.msg_w) * (val & params.msg_mask())) >> params.msg_w) & params.msg_mask();
573 if mul_msb != 0 { 1} else {0}
574 };
575 |params: &DigitParameters, _deg| params.msg_mask();
576 }
577]],
578["IsNull" => 38 [
579 @0 =>{
580 |params: &DigitParameters, val | {
581 let carry_field = (val & params.carry_mask()) >> params.msg_w;
582 let msg_field = val & params.msg_mask();
583
584 match (carry_field,msg_field) {
585 (0,0) => 1,
586 _ => 0,
587 }
588 };
589 |_params: &DigitParameters, _deg| 1;
590 }
591]],
592["IsNullPos1" => 39 [ @0 =>{
594 |params: &DigitParameters, val | {
595 let carry_field = (val & params.carry_mask()) >> params.msg_w;
596 let msg_field = val & params.msg_mask();
597
598 match (carry_field,msg_field) {
599 (0,0) => 1 << 1,
600 _ => 0,
601 }
602 };
603 |_params: &DigitParameters, _deg| 1 << 1;
604 }
605]],
606["NotNull" => 40 [
607 @0 =>{
608 |params: &DigitParameters, val | {
609 let carry_field = (val & params.carry_mask()) >> params.msg_w;
610 let msg_field = val & params.msg_mask();
611
612 match (carry_field,msg_field) {
613 (0,0) => 0,
614 _ => 1,
615 }
616 };
617 |_params: &DigitParameters, _deg| 1;
618 }
619]],
620["MsgNotNull" => 41 [
621 @0 =>{
622 |params: &DigitParameters, val | {
623 let msg_field = val & params.msg_mask();
624
625 match msg_field {
626 0 => 0,
627 _ => 1,
628 }
629 };
630 |_params: &DigitParameters, _deg| 1;
631 }
632]],
633["MsgNotNullPos1" => 42 [ @0 =>{
637 |params: &DigitParameters, val | {
638 let msg_field = val & params.msg_mask();
639
640 match msg_field {
641 0 => 0,
642 _ => 1 << 1,
643 }
644 };
645 |_params: &DigitParameters, _deg| 1 << 1;
646 }
647]],
648["ManyMsgSplitShift1" => 43 [ @0 =>{
651 |params: &DigitParameters, val| {
652 let lsb_size = params.msg_w.div_ceil(2);
653 let msg_lsb = val & ((1 << lsb_size)-1);
654 msg_lsb << lsb_size
655 };
656 |params: &DigitParameters, _deg| {
657 let lsb_size = params.msg_w.div_ceil(2);
658 ((1 << lsb_size)-1) << lsb_size
659 };
660 },
661 @1 =>{
662 |params: &DigitParameters, val| {
663 let lsb_size = params.msg_w.div_ceil(2);
664 (val & params.msg_mask()) >> lsb_size };
666 |params: &DigitParameters, _deg| {
667 let lsb_size = params.msg_w.div_ceil(2);
668 let msb_size = params.msg_w - lsb_size;
669 (1 << msb_size)-1
670 };
671 }
672]],
673["SolvePropGroupFinal0" => 44 [ @0 =>{
683 |_params: &DigitParameters, val | {
684 let position = 0;
685 let pos_w = position + 2;
686 (val >> (pos_w-1)) & 1_usize };
688 |_params: &DigitParameters, _deg| 1;
689 }
690]],
691["SolvePropGroupFinal1" => 45 [ @0 =>{
701 |_params: &DigitParameters, val | {
702 let position = 1;
703 let pos_w = position + 2;
704 (val >> (pos_w-1)) & 1_usize };
706 |_params: &DigitParameters, _deg| 1;
707 }
708]],
709["SolvePropGroupFinal2" => 46 [ @0 =>{
719 |_params: &DigitParameters, val | {
720 let position = 2;
721 let pos_w = position + 2;
722 (val >> (pos_w-1)) & 1_usize };
724 |_params: &DigitParameters, _deg| 1;
725 }
726]],
727["ExtractPropGroup0" => 47 [ @0 =>{
731 |params: &DigitParameters, val | {
732 let position = 0;
733 let msg = val & params.msg_mask();
734 let carry = (val >> params.msg_w) & 1_usize;
735 if carry == 1 {
736 2 << position } else if msg == params.msg_mask() {
738 1 << position } else {
740 0 << position }
742 };
743 |_params: &DigitParameters, _deg| {
744 let position = 0;
745 2 << position
746 };
747 }
748]],
749["ExtractPropGroup1" => 48 [ @0 =>{
753 |params: &DigitParameters, val | {
754 let position = 1;
755 let msg = val & params.msg_mask();
756 let carry = (val >> params.msg_w) & 1_usize;
757 if carry == 1 {
758 2 << position } else if msg == params.msg_mask() {
760 1 << position } else {
762 0 << position }
764 };
765 |_params: &DigitParameters, _deg| {
766 let position = 1;
767 2 << position
768 };
769 }
770]],
771["ExtractPropGroup2" => 49 [ @0 =>{
775 |params: &DigitParameters, val | {
776 let position = 2;
777 let msg = val & params.msg_mask();
778 let carry = (val >> params.msg_w) & 1_usize;
779 if carry == 1 {
780 2 << position } else if msg == params.msg_mask() {
782 1 << position } else {
784 0 << position }
786 };
787 |_params: &DigitParameters, _deg| {
788 let position = 2;
789 2 << position
790 };
791 }
792]],
793["ExtractPropGroup3" => 50 [ @0 =>{
797 |params: &DigitParameters, val | {
798 let position = 3;
799 let msg = val & params.msg_mask();
800 let carry = (val >> params.msg_w) & 1_usize;
801 if carry == 1 {
802 2 << position } else if msg == params.msg_mask() {
804 1 << position } else {
806 0 << position }
808 };
809 |_params: &DigitParameters, _deg| {
810 let position = 3;
811 2 << position
812 };
813 }
814]],
815["SolveProp" => 51 [ @0 =>{
820 |params: &DigitParameters, val | {
821 let msb = (val >> params.msg_w) & params.msg_mask();
822 let lsb = val & params.msg_mask();
823
824 if msb == 1 { lsb
826 } else {
827 msb
828 }
829 };
830 |_params: &DigitParameters, _deg| 2;
831 }
832]],
833["SolvePropCarry" => 52 [ @0 =>{
839 |params: &DigitParameters, val | {
840 let msb = (val >> params.msg_w) & params.msg_mask();
841 let lsb = val & params.msg_mask();
842
843 if msb == 1 { lsb
845 } else {
846 msb >> 1 }
848 };
849 |_params: &DigitParameters, _deg| 2;
850 }
851]],
852["SolveQuotient" => 53 [ @0 =>{
862 |params: &DigitParameters, val | {
863 let v = val & params.data_mask();
864
865 match v {
866 0 => 3,
867 1 => 2,
868 2 => 1,
869 3 => 0,
870 _ => 0,
871 }
873 };
874 |_params: &DigitParameters, _deg| 3;
875 }
876]],
877["SolveQuotientPos1" => 54 [ @0 =>{
889 |params: &DigitParameters, val | {
890 let v = val & params.data_mask();
891
892 match v {
893 0 => 3,
894 2 => 2,
895 4 => 1,
896 6 => 0,
897 _ => 0,
898 }
900 };
901 |_params: &DigitParameters, _deg| 3;
902 }
903]],
904["IfPos1FalseZeroed" => 55 [ @0 =>{
906 |params: &DigitParameters, val | {
907 let value = val & params.msg_mask();
908 let cond = (val >> (params.msg_w + 1)) & 1;
909 if cond != 0 {value} else {0}
910 };
911 |params: &DigitParameters, _deg| params.msg_mask();
912 }
913]],
914["IfPos1FalseZeroedMsgCarry1" => 56 [ @0 =>{
917 |params: &DigitParameters, val | {
918 let value = val & (params.msg_mask() * 2 + 1);
919 let cond = (val >> (params.msg_w + 1)) & 1;
920 if cond != 0 {value} else {0}
921 };
922 |params: &DigitParameters, _deg| params.msg_mask();
923 }
924]],
925
926["ShiftLeftByCarryPos0Msg" => 57 [ @0 =>{
929 |params: &DigitParameters, val | {
930 let value = val & params.msg_mask();
931 let shift = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
932 (value << shift) & params.msg_mask()
933 };
934 |params: &DigitParameters, _deg| params.msg_mask();
935 }
936]],
937["ShiftLeftByCarryPos0MsgNext" => 58 [ @0 =>{
939 |params: &DigitParameters, val | {
940 let value = val & params.msg_mask();
941 let shift = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
942 ((value << shift) & params.carry_mask()) >> params.msg_w
943 };
944 |params: &DigitParameters, _deg| params.msg_mask();
945 }
946]],
947
948["ShiftRightByCarryPos0Msg" => 59 [ @0 =>{
950 |params: &DigitParameters, val | {
951 let value = val & params.msg_mask();
952 let shift = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
953 (value >> shift) & params.msg_mask()
954 };
955 |params: &DigitParameters, _deg| params.msg_mask();
956 }
957]],
958["ShiftRightByCarryPos0MsgNext" => 60 [ @0 =>{
961 |params: &DigitParameters, val | {
962 let value = val & params.msg_mask();
963 let shift = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
964 ((value << params.msg_w) >> shift) & params.msg_mask()
965 };
966 |params: &DigitParameters, _deg| params.msg_mask();
967 }
968]],
969["IfPos0TrueZeroed" => 61 [ @0 =>{
972 |params: &DigitParameters, val | {
973 let value = val & params.msg_mask();
974 let cond = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
975 if cond != 0 {0} else {value}
976 };
977 |params: &DigitParameters, _deg| params.msg_mask();
978 }
979]],
980["IfPos0FalseZeroed" => 62 [ @0 =>{
982 |params: &DigitParameters, val | {
983 let value = val & params.msg_mask();
984 let cond = ((val & params.carry_mask()) >> params.msg_w) & 0x1;
985 if cond != 0 {value} else {0}
986 };
987 |params: &DigitParameters, _deg| params.msg_mask();
988 }
989]],
990["IfPos1TrueZeroed" => 63 [ @0 =>{
993 |params: &DigitParameters, val | {
994 let value = val & params.msg_mask();
995 let cond = ((val & params.carry_mask()) >> params.msg_w) & 0x2;
996 if cond != 0 {0} else {value}
997 };
998 |params: &DigitParameters, _deg| params.msg_mask();
999 }
1000]],
1001["ManyInv1CarryMsg" => 64 [ @0 =>{
1005 |params: &DigitParameters, val | {
1006 let inv = 1;
1007 let mut value = val & params.data_mask();
1008 if value > inv {
1009 0
1010 } else {
1011 value = inv - value;
1012 value & params.msg_mask()
1013 }
1014 };
1015 |params: &DigitParameters, _deg| params.msg_mask();
1016 },
1017 @1 =>{
1018 |params: &DigitParameters, val | {
1019 let inv = 1;
1020 let mut value = val & params.data_mask();
1021 if value > inv {
1022 0
1023 } else {
1024 value = inv - value;
1025 value >> params.msg_w
1026 }
1027 };
1028 |_params: &DigitParameters, _deg| 1;
1029 },
1030]],
1031["ManyInv2CarryMsg" => 65 [ @0 =>{
1034 |params: &DigitParameters, val | {
1035 let inv = 2;
1036 let mut value = val & params.data_mask();
1037 if value > inv {
1038 0
1039 } else {
1040 value = inv - value;
1041 value & params.msg_mask()
1042 }
1043 };
1044 |params: &DigitParameters, _deg| params.msg_mask();
1045 },
1046 @1 =>{
1047 |params: &DigitParameters, val | {
1048 let inv = 2;
1049 let mut value = val & params.data_mask();
1050 if value > inv {
1051 0
1052 } else {
1053 value = inv - value;
1054 value >> params.msg_w
1055 }
1056 };
1057 |_params: &DigitParameters, _deg| 1;
1058 },
1059]],
1060
1061["ManyInv3CarryMsg" => 66 [ @0 =>{
1064 |params: &DigitParameters, val | {
1065 let inv = 3;
1066 let mut value = val & params.data_mask();
1067 if value > inv {
1068 0
1069 } else {
1070 value = inv - value;
1071 value & params.msg_mask()
1072 }
1073 };
1074 |params: &DigitParameters, _deg| params.msg_mask();
1075 },
1076 @1 =>{
1077 |params: &DigitParameters, val | {
1078 let inv = 3;
1079 let mut value = val & params.data_mask();
1080 if value > inv {
1081 0
1082 } else {
1083 value = inv - value;
1084 value >> params.msg_w
1085 }
1086 };
1087 |_params: &DigitParameters, _deg| 1;
1088 },
1089]],
1090
1091["ManyInv4CarryMsg" => 67 [ @0 =>{
1094 |params: &DigitParameters, val | {
1095 let inv = 4;
1096 let mut value = val & params.data_mask();
1097 if value > inv {
1098 0
1099 } else {
1100 value = inv - value;
1101 value & params.msg_mask()
1102 }
1103 };
1104 |params: &DigitParameters, _deg| params.msg_mask();
1105 },
1106 @1 =>{
1107 |params: &DigitParameters, val | {
1108 let inv = 4;
1109 let mut value = val & params.data_mask();
1110 if value > inv {
1111 0
1112 } else {
1113 value = inv - value;
1114 value >> params.msg_w
1115 }
1116 };
1117 |_params: &DigitParameters, _deg| 1;
1118 },
1119]],
1120
1121["ManyInv5CarryMsg" => 68 [ @0 =>{
1124 |params: &DigitParameters, val | {
1125 let inv = 5;
1126 let mut value = val & params.data_mask();
1127 if value > inv {
1128 0
1129 } else {
1130 value = inv - value;
1131 value & params.msg_mask()
1132 }
1133 };
1134 |params: &DigitParameters, _deg| params.msg_mask();
1135 },
1136 @1 =>{
1137 |params: &DigitParameters, val | {
1138 let inv = 5;
1139 let mut value = val & params.data_mask();
1140 if value > inv {
1141 0
1142 } else {
1143 value = inv - value;
1144 value >> params.msg_w
1145 }
1146 };
1147 |_params: &DigitParameters, _deg| 1;
1148 },
1149]],
1150
1151["ManyInv6CarryMsg" => 69 [ @0 =>{
1154 |params: &DigitParameters, val | {
1155 let inv = 6;
1156 let mut value = val & params.data_mask();
1157 if value > inv {
1158 0
1159 } else {
1160 value = inv - value;
1161 value & params.msg_mask()
1162 }
1163 };
1164 |params: &DigitParameters, _deg| params.msg_mask();
1165 },
1166 @1 =>{
1167 |params: &DigitParameters, val | {
1168 let inv = 6;
1169 let mut value = val & params.data_mask();
1170 if value > inv {
1171 0
1172 } else {
1173 value = inv - value;
1174 value >> params.msg_w
1175 }
1176 };
1177 |_params: &DigitParameters, _deg| 1;
1178 },
1179]],
1180
1181["ManyInv7CarryMsg" => 70 [ @0 =>{
1184 |params: &DigitParameters, val | {
1185 let inv = 7;
1186 let mut value = val & params.data_mask();
1187 if value > inv {
1188 0
1189 } else {
1190 value = inv - value;
1191 value & params.msg_mask()
1192 }
1193 };
1194 |params: &DigitParameters, _deg| params.msg_mask();
1195 },
1196 @1 =>{
1197 |params: &DigitParameters, val | {
1198 let inv = 7;
1199 let mut value = val & params.data_mask();
1200 if value > inv {
1201 0
1202 } else {
1203 value = inv - value;
1204 value >> params.msg_w
1205 }
1206 };
1207 |_params: &DigitParameters, _deg| 1;
1208 },
1209]],
1210["ManyMsgSplit" => 71 [ @0 =>{
1212 |params: &DigitParameters, val| {
1213 let lsb_size = params.msg_w.div_ceil(2);
1214 val & ((1 << lsb_size)-1) };
1216 |params: &DigitParameters, _deg| {
1217 let lsb_size = params.msg_w.div_ceil(2);
1218 (1 << lsb_size)-1
1219 };
1220 },
1221 @1 =>{
1222 |params: &DigitParameters, val| {
1223 let lsb_size = params.msg_w.div_ceil(2);
1224 (val & params.msg_mask()) >> lsb_size };
1226 |params: &DigitParameters, _deg| {
1227 let lsb_size = params.msg_w.div_ceil(2);
1228 let msb_size = params.msg_w - lsb_size;
1229 (1 << msb_size)-1
1230 };
1231 }
1232]],
1233["Manym2lPropBit1MsgSplit" => 72 [ @0 =>{
1239 |params: &DigitParameters, val| {
1240 let mut c = val & params.carry_mask();
1241 let mut m = val & params.msg_mask();
1242 let mut exp = 0;
1243 for idx in (0..params.msg_w).rev() {
1245 let mut b = (m >> idx) & 1;
1246 m &= (1 << idx)-1;
1247 if c > 0 {b = 1;} if b == 1 {c = 1;}
1249 exp += b << idx;
1250 }
1251 let lsb_size = params.msg_w.div_ceil(2);
1252 exp & ((1 << lsb_size)-1) };
1254 |params: &DigitParameters, _deg| {
1255 let lsb_size = params.msg_w.div_ceil(2);
1256 (1 << lsb_size)-1
1257 };
1258 },
1259 @1 =>{
1260 |params: &DigitParameters, val| {
1261 let mut c = val & params.carry_mask();
1262 let mut m = val & params.msg_mask();
1263 let mut exp = 0;
1264 for idx in (0..params.msg_w).rev() {
1266 let mut b = (m >> idx) & 1;
1267 m &= (1 << idx)-1;
1268 if c > 0 {b = 1;} if b == 1 {c = 1;}
1270 exp += b << idx;
1271 }
1272 let lsb_size = params.msg_w.div_ceil(2);
1273 (exp & params.msg_mask()) >> lsb_size };
1275 |params: &DigitParameters, _deg| {
1276 let lsb_size = params.msg_w.div_ceil(2);
1277 let msb_size = params.msg_w - lsb_size;
1278 (1 << msb_size)-1
1279 };
1280 }
1281]],
1282["Manym2lPropBit0MsgSplit" => 73 [ @0 =>{
1288 |params: &DigitParameters, val| {
1289 let mut c = val & params.carry_mask();
1290 let mut m = val & params.msg_mask();
1291 let mut exp = 0;
1292 for idx in (0..(params.msg_w)).rev() {
1294 let mut b = (m >> idx) & 1;
1295 m &= (1 << idx)-1;
1296 if c > 0 {b = 0;} if b == 0 {c = 1;}
1298 exp += b << idx;
1299 }
1300 let lsb_size = params.msg_w.div_ceil(2);
1301 exp & ((1 << lsb_size)-1) };
1303 |params: &DigitParameters, _deg| {
1304 let lsb_size = params.msg_w.div_ceil(2);
1305 (1 << lsb_size)-1
1306 };
1307 },
1308 @1 =>{
1309 |params: &DigitParameters, val| {
1310 let mut c = val & params.carry_mask();
1311 let mut m = val & params.msg_mask();
1312 let mut exp = 0;
1313 for idx in (0..(params.msg_w)).rev() {
1315 let mut b = (m >> idx) & 1;
1316 m &= (1 << idx)-1;
1317 if c > 0 {b = 0;} if b == 0 {c = 1;}
1319 exp += b << idx;
1320 }
1321 let lsb_size = params.msg_w.div_ceil(2);
1322 (exp & params.msg_mask()) >> lsb_size };
1324 |params: &DigitParameters, _deg| {
1325 let lsb_size = params.msg_w.div_ceil(2);
1326 let msb_size = params.msg_w - lsb_size;
1327 (1 << msb_size)-1
1328 };
1329 }
1330]],
1331["Manyl2mPropBit1MsgSplit" => 74 [ @0 =>{
1337 |params: &DigitParameters, val| {
1338 let mut c = val & params.carry_mask();
1339 let mut m = val & params.msg_mask();
1340 let mut exp = 0;
1341 for idx in 0..(params.msg_w) {
1343 let mut b = m & 1;
1344 m >>= 1;
1345 if c > 0 {b = 1;} if b == 1 {c = 1;}
1347 exp += b << idx;
1348 }
1349 let lsb_size = params.msg_w.div_ceil(2);
1350 exp & ((1 << lsb_size)-1) };
1352 |params: &DigitParameters, _deg| {
1353 let lsb_size = params.msg_w.div_ceil(2);
1354 (1 << lsb_size)-1
1355 };
1356 },
1357 @1 =>{
1358 |params: &DigitParameters, val| {
1359 let mut c = val & params.carry_mask();
1360 let mut m = val & params.msg_mask();
1361 let mut exp = 0;
1362 for idx in 0..(params.msg_w) {
1364 let mut b = m & 1;
1365 m >>= 1;
1366 if c > 0 {b = 1;} if b == 1 {c = 1;}
1368 exp += b << idx;
1369 }
1370 let lsb_size = params.msg_w.div_ceil(2);
1371 (exp & params.msg_mask()) >> lsb_size };
1373 |params: &DigitParameters, _deg| {
1374 let lsb_size = params.msg_w.div_ceil(2);
1375 let msb_size = params.msg_w - lsb_size;
1376 (1 << msb_size)-1
1377 };
1378 }
1379]],
1380["Manyl2mPropBit0MsgSplit" => 75 [ @0 =>{
1386 |params: &DigitParameters, val| {
1387 let mut c = val & params.carry_mask();
1388 let mut m = val & params.msg_mask();
1389 let mut exp = 0;
1390 for idx in 0..(params.msg_w) {
1392 let mut b = m & 1;
1393 m >>= 1;
1394 if c > 0 {b = 0;} if b == 0 {c = 1;}
1396 exp += b << idx;
1397 }
1398 let lsb_size = params.msg_w.div_ceil(2);
1399 exp & ((1 << lsb_size)-1) };
1401 |params: &DigitParameters, _deg| {
1402 let lsb_size = params.msg_w.div_ceil(2);
1403 (1 << lsb_size)-1
1404 };
1405 },
1406 @1 =>{
1407 |params: &DigitParameters, val| {
1408 let mut c = val & params.carry_mask();
1409 let mut m = val & params.msg_mask();
1410 let mut exp = 0;
1411 for idx in 0..(params.msg_w) {
1413 let mut b = m & 1;
1414 m >>= 1;
1415 if c > 0 {b = 0;} if b == 0 {c = 1;}
1417 exp += b << idx;
1418 }
1419 let lsb_size = params.msg_w.div_ceil(2);
1420 (exp & params.msg_mask()) >> lsb_size };
1422 |params: &DigitParameters, _deg| {
1423 let lsb_size = params.msg_w.div_ceil(2);
1424 let msb_size = params.msg_w - lsb_size;
1425 (1 << msb_size)-1
1426 };
1427 }
1428]],
1429);
1430
1431pub(crate) fn ceil_ilog2(value: &u8) -> u8 {
1432 (value.ilog2() + u32::from(!value.is_power_of_two())) as u8
1433}