luaur_code_gen/methods/
const_prop_state_get_offset_base.rs1use 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}