luaur_code_gen/functions/
call_arith_helper.rs1use 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); 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}