Skip to main content

luaur_code_gen/functions/
call_arith_helper.rs

1use crate::enums::size_x_64::SizeX64;
2use crate::functions::emit_update_base_emit_common_x_64::emit_update_base;
3use crate::functions::luau_reg_address::luau_reg_address;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
6use crate::records::ir_call_wrapper_x_64::IrCallWrapperX64;
7use crate::records::ir_data::k_invalid_inst_idx;
8use crate::records::ir_op::IrOp;
9use crate::records::ir_reg_alloc_x_64::IrRegAllocX64;
10use crate::records::native_context::NativeContext;
11use crate::records::operand_x_64::OperandX64;
12use crate::records::register_x_64::RegisterX64;
13use luaur_vm::type_aliases::tms::TMS;
14
15const fn r_state() -> RegisterX64 {
16    RegisterX64 {
17        bits: (15u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
18    }
19}
20
21const fn r_native_context() -> RegisterX64 {
22    RegisterX64 {
23        bits: (13u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
24    }
25}
26
27pub fn call_arith_helper(
28    regs: &mut IrRegAllocX64,
29    build: &mut AssemblyBuilderX64,
30    ra: i32,
31    b: OperandX64,
32    c: OperandX64,
33    tm: TMS,
34) {
35    let mut call_wrap = IrCallWrapperX64::ir_call_wrapper_x_64_ir_call_wrapper_x_64(
36        regs,
37        build,
38        k_invalid_inst_idx,
39    );
40
41    call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
42        SizeX64::qword,
43        OperandX64::reg(r_state()),
44        IrOp::ir_op(),
45    );
46    call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
47        SizeX64::qword,
48        luau_reg_address(ra),
49        IrOp::ir_op(),
50    );
51    call_wrap.add_argument_size_x_64_operand_x_64_ir_op(SizeX64::qword, b, IrOp::ir_op());
52    call_wrap.add_argument_size_x_64_operand_x_64_ir_op(SizeX64::qword, c, IrOp::ir_op());
53
54    let off = match tm {
55        TMS::TM_ADD => core::mem::offset_of!(NativeContext, luaV_doarithadd),
56        TMS::TM_SUB => core::mem::offset_of!(NativeContext, luaV_doarithsub),
57        TMS::TM_MUL => core::mem::offset_of!(NativeContext, luaV_doarithmul),
58        TMS::TM_DIV => core::mem::offset_of!(NativeContext, luaV_doarithdiv),
59        TMS::TM_IDIV => core::mem::offset_of!(NativeContext, luaV_doarithidiv),
60        TMS::TM_MOD => core::mem::offset_of!(NativeContext, luaV_doarithmod),
61        TMS::TM_POW => core::mem::offset_of!(NativeContext, luaV_doarithpow),
62        TMS::TM_UNM => core::mem::offset_of!(NativeContext, luaV_doarithunm),
63        _ => {
64            CODEGEN_ASSERT!(false); // "Invalid doarith helper operation tag"
65            0
66        }
67    } as i32;
68
69    call_wrap.call(&OperandX64::mem(
70        SizeX64::qword,
71        RegisterX64::noreg,
72        1,
73        r_native_context(),
74        off,
75    ));
76
77    emit_update_base(build);
78}