Skip to main content

ironwork_rt/lir/
arith.rs

1//! Arithmetic plans (lir.md ยง7): what the walker works out on each execution, fixed at lowering.
2
3use super::{AbendId, ExprId, PlaceId, SymId};
4use crate::vocab::SignClause;
5use crate::{codec_enum, codec_struct};
6use numeric::Arith;
7use zarch::hfp::Precision;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct ArithPlan {
11    pub dmax: u32,
12    pub arith: Arith,
13    /// The places the walker's dmax pre-pass locates, in its order, static ones left out.
14    pub prepass: Vec<PlaceId>,
15    pub steps: Vec<ArithStep>,
16    pub remainder: Option<RemainderPlan>,
17    /// ON or NOT ON SIZE ERROR is written.
18    pub handled: bool,
19}
20
21/// `probe` holds the places the walker's float test locates after the receiver, static ones left out.
22#[derive(Clone, Debug, PartialEq, Eq)]
23pub struct ArithStep {
24    pub target: PlaceId,
25    pub expr: ExprId,
26    pub mode: Mode,
27    pub store: StorePlan,
28    pub rounded: bool,
29    pub probe: Vec<PlaceId>,
30}
31
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum Mode {
34    Fixed,
35    Float(Precision),
36}
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub enum StorePlan {
40    Zoned { digits: u32, scale: u32, signed: bool, sign: Option<SignClause> },
41    Packed { digits: u32, scale: u32, signed: bool },
42    /// `name` labels a TRUNC(OPT) report.
43    Binary { digits: u32, scale: u32, signed: bool, native: bool, name: SymId },
44    NumericEdited { edit: u32, digits: u32, scale: u32, blank_when_zero: bool },
45    Float(Precision),
46    Index,
47    Refused(AbendId),
48}
49
50#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub struct RemainderPlan {
52    pub target: PlaceId,
53    pub dividend: ExprId,
54    pub divisor: ExprId,
55    pub quotient_scale: u32,
56    pub store: StorePlan,
57}
58
59/// PERFORM VARYING's step, SET UP and DOWN BY, and the TALLYING adds: no ROUNDED, no size error.
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
61pub struct StepPlan {
62    pub dmax: u32,
63    pub store: StorePlan,
64}
65
66codec_struct!(ArithPlan { dmax, arith, prepass, steps, remainder, handled });
67codec_struct!(ArithStep { target, expr, mode, store, rounded, probe });
68codec_enum!(Mode { Fixed = 0, Float(precision) = 1 });
69codec_enum!(StorePlan {
70    Zoned { digits, scale, signed, sign } = 0,
71    Packed { digits, scale, signed } = 1,
72    Binary { digits, scale, signed, native, name } = 2,
73    NumericEdited { edit, digits, scale, blank_when_zero } = 3,
74    Float(precision) = 4,
75    Index = 5,
76    Refused(abend) = 6,
77});
78codec_struct!(RemainderPlan { target, dividend, divisor, quotient_scale, store });
79codec_struct!(StepPlan { dmax, store });