Skip to main content

luaur_code_gen/methods/
const_prop_state_get_offset_base.rs

1use crate::enums::ir_cmd::IrCmd;
2use crate::enums::ir_op_kind::IrOpKind;
3use crate::macros::op_a::op_a;
4use crate::macros::op_b::op_b;
5use crate::macros::opt_op_a::OPT_OP_A;
6use crate::macros::opt_op_b::OPT_OP_B;
7use crate::records::buffer_access_base::BufferAccessBase;
8use crate::records::const_prop_state::ConstPropState;
9use crate::records::ir_op::IrOp;
10
11impl ConstPropState {
12    pub fn get_offset_base(&mut self, value: IrOp) -> BufferAccessBase {
13        let mut base = BufferAccessBase {
14            op: value,
15            scale: 1,
16            offset: 0,
17        };
18
19        loop {
20            if base.op.kind() != IrOpKind::Inst {
21                break;
22            }
23
24            let inst = unsafe { (*self.function).inst_op(base.op).clone() };
25            let lhs_num = unsafe { (*self.function).as_double_op(OPT_OP_A(inst.clone())) };
26            let rhs_num = unsafe { (*self.function).as_double_op(OPT_OP_B(inst.clone())) };
27            let lhs_int = unsafe { (*self.function).as_int_op(OPT_OP_A(inst.clone())) };
28            let rhs_int = unsafe { (*self.function).as_int_op(OPT_OP_B(inst.clone())) };
29
30            if inst.cmd == IrCmd::ADD_NUM
31                && lhs_num.is_some()
32                && self.is_valid_double_for_immediate(lhs_num.unwrap())
33            {
34                base.offset += (lhs_num.unwrap() as i32) * base.scale;
35                base.op = op_b(inst);
36            } else if inst.cmd == IrCmd::ADD_NUM
37                && rhs_num.is_some()
38                && self.is_valid_double_for_immediate(rhs_num.unwrap())
39            {
40                base.offset += (rhs_num.unwrap() as i32) * base.scale;
41                base.op = op_a(&mut inst.clone());
42            } else if inst.cmd == IrCmd::SUB_NUM
43                && rhs_num.is_some()
44                && self.is_valid_double_for_immediate(rhs_num.unwrap())
45            {
46                base.offset -= (rhs_num.unwrap() as i32) * base.scale;
47                base.op = op_a(&mut inst.clone());
48            } else if inst.cmd == IrCmd::MUL_NUM
49                && lhs_num.is_some()
50                && self.is_valid_double_for_immediate(lhs_num.unwrap())
51            {
52                base.scale *= lhs_num.unwrap() as i32;
53                base.op = op_b(inst);
54            } else if inst.cmd == IrCmd::MUL_NUM
55                && rhs_num.is_some()
56                && self.is_valid_double_for_immediate(rhs_num.unwrap())
57            {
58                base.scale *= rhs_num.unwrap() as i32;
59                base.op = op_a(&mut inst.clone());
60            } else if inst.cmd == IrCmd::ADD_INT
61                && lhs_int.is_some()
62                && self.is_valid_integer_for_immediate(lhs_int.unwrap())
63            {
64                base.offset += lhs_int.unwrap() * base.scale;
65                base.op = op_b(inst);
66            } else if inst.cmd == IrCmd::ADD_INT
67                && rhs_int.is_some()
68                && self.is_valid_integer_for_immediate(rhs_int.unwrap())
69            {
70                base.offset += rhs_int.unwrap() * base.scale;
71                base.op = op_a(&mut inst.clone());
72            } else if inst.cmd == IrCmd::SUB_INT
73                && rhs_int.is_some()
74                && self.is_valid_integer_for_immediate(rhs_int.unwrap())
75            {
76                base.offset -= rhs_int.unwrap() * base.scale;
77                base.op = op_a(&mut inst.clone());
78            } else if inst.cmd == IrCmd::TRUNCATE_UINT {
79                base.op = op_a(&mut inst.clone());
80            } else {
81                break;
82            }
83
84            if !self.is_valid_integer_for_immediate(base.offset)
85                || !self.is_valid_integer_for_immediate(base.scale)
86            {
87                break;
88            }
89        }
90
91        base
92    }
93}