Skip to main content

luaur_code_gen/functions/
call_barrier_object.rs

1use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
2use crate::records::ir_call_wrapper_x_64::IrCallWrapperX64;
3use crate::records::ir_op::IrOp;
4use crate::records::ir_reg_alloc_x_64::IrRegAllocX64;
5use crate::records::label::Label;
6use crate::records::native_context::NativeContext;
7use crate::records::operand_x_64::OperandX64;
8use crate::records::register_x_64::RegisterX64;
9use crate::records::scoped_reg_x_64::ScopedRegX64;
10use crate::records::scoped_spills::ScopedSpills;
11
12use crate::enums::size_x_64::SizeX64;
13
14use crate::functions::check_object_barrier_conditions::check_object_barrier_conditions;
15
16const fn r_state() -> RegisterX64 {
17    RegisterX64 {
18        bits: (15u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
19    }
20}
21
22const fn r_native_context() -> RegisterX64 {
23    RegisterX64 {
24        bits: (13u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
25    }
26}
27
28pub fn call_barrier_object(
29    regs: &mut IrRegAllocX64,
30    build: &mut AssemblyBuilderX64,
31    object: RegisterX64,
32    object_op: IrOp,
33    ra: RegisterX64,
34    ra_op: IrOp,
35    ratag: i32,
36) {
37    let mut skip = Label { id: 0, location: 0 };
38
39    let mut tmp = ScopedRegX64 {
40        owner: regs as *mut _,
41        reg: RegisterX64::noreg,
42    };
43    tmp.scoped_reg_x_64_ir_reg_alloc_x_64_size_x_64(regs, SizeX64::qword);
44
45    check_object_barrier_conditions(build, tmp.reg, object, ra, ra_op, ratag, &mut skip);
46
47    {
48        let _spill_guard = {
49            let mut guard = ScopedSpills {
50                owner: regs as *mut _,
51                start_spill_id: 0,
52            };
53            guard.scoped_spills_scoped_spills_ir_reg_alloc_x_64(regs);
54            guard
55        };
56
57        let mut call_wrap = IrCallWrapperX64::ir_call_wrapper_x_64_ir_call_wrapper_x_64(
58            regs,
59            build,
60            regs.curr_inst_idx,
61        );
62
63        call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
64            SizeX64::qword,
65            OperandX64::reg(r_state()),
66            IrOp::ir_op(),
67        );
68
69        call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
70            SizeX64::qword,
71            OperandX64::reg(object),
72            object_op,
73        );
74
75        call_wrap.add_argument_size_x_64_scoped_reg_x_64(SizeX64::qword, &mut tmp);
76
77        let barrierf_offset = core::mem::offset_of!(NativeContext, luaC_barrierf) as i32;
78        let target = OperandX64::mem(
79            SizeX64::qword,
80            RegisterX64::noreg,
81            1,
82            r_native_context(),
83            barrierf_offset,
84        );
85
86        call_wrap.call(&target);
87    }
88
89    build.set_label_label(&mut skip);
90}