luaur_code_gen/functions/
emit_fallback_emit_common_x_64.rs1use crate::enums::size_x_64::SizeX64;
2use crate::functions::emit_update_base_emit_common_x_64::emit_update_base;
3use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
4use crate::records::ir_call_wrapper_x_64::IrCallWrapperX64;
5use crate::records::ir_data::k_invalid_inst_idx;
6use crate::records::ir_op::IrOp;
7use crate::records::ir_reg_alloc_x_64::IrRegAllocX64;
8use crate::records::operand_x_64::OperandX64;
9use crate::records::register_x_64::RegisterX64;
10
11const fn r_state() -> RegisterX64 {
12 RegisterX64 {
13 bits: (15u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
14 }
15}
16
17const fn r_constants() -> RegisterX64 {
19 RegisterX64 {
20 bits: (12u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
21 }
22}
23
24const fn r_native_context() -> RegisterX64 {
26 RegisterX64 {
27 bits: (13u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
28 }
29}
30
31const K_STACK_OFFSET_TO_LOCALS: i32 = 16 + 32;
32
33fn s_code() -> OperandX64 {
34 OperandX64::mem(
35 SizeX64::qword,
36 RegisterX64::noreg,
37 1,
38 RegisterX64::rsp,
39 K_STACK_OFFSET_TO_LOCALS + 8,
40 )
41}
42
43const SIZEOF_INSTRUCTION: i32 = 4;
44
45pub fn emit_fallback(
46 regs: &mut IrRegAllocX64,
47 build: &mut AssemblyBuilderX64,
48 offset: i32,
49 pcpos: i32,
50) {
51 let mut call_wrap = IrCallWrapperX64::ir_call_wrapper_x_64_ir_call_wrapper_x_64(
53 regs,
54 build,
55 k_invalid_inst_idx,
56 );
57
58 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
59 SizeX64::qword,
60 OperandX64::reg(r_state()),
61 IrOp::ir_op(),
62 );
63
64 let reg = call_wrap.suggest_next_argument_register(SizeX64::qword);
65 build.mov(OperandX64::reg(reg), s_code());
66 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
67 SizeX64::qword,
68 OperandX64::mem(
69 SizeX64::none,
70 RegisterX64::noreg,
71 1,
72 reg,
73 pcpos * SIZEOF_INSTRUCTION,
74 ),
75 IrOp::ir_op(),
76 );
77
78 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
80 SizeX64::qword,
81 OperandX64::reg(RegisterX64::rbp),
82 IrOp::ir_op(),
83 );
84 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
85 SizeX64::qword,
86 OperandX64::reg(r_constants()),
87 IrOp::ir_op(),
88 );
89
90 call_wrap.call(&OperandX64::mem(
91 SizeX64::qword,
92 RegisterX64::noreg,
93 1,
94 r_native_context(),
95 offset,
96 ));
97
98 emit_update_base(build);
99}