luaur_code_gen/functions/
emit_continue_call.rs1use crate::enums::address_kind_a_64::AddressKindA64;
2use crate::enums::kind_a_64::KindA64;
3use crate::macros::call_fallback_yield::CALL_FALLBACK_YIELD;
4use crate::records::address_a_64::AddressA64;
5use crate::records::assembly_builder_a_64::AssemblyBuilderA64;
6use crate::records::module_helpers::ModuleHelpers;
7use crate::records::register_a_64::RegisterA64;
8use luaur_vm::records::closure::{Closure, LClosure};
9use luaur_vm::records::proto::Proto;
10
11const fn reg(kind: KindA64, index: u8) -> RegisterA64 {
12 RegisterA64 {
13 bits: kind as u8 | (index << 3),
14 }
15}
16
17const X0: RegisterA64 = reg(KindA64::x, 0);
18const X1: RegisterA64 = reg(KindA64::x, 1);
19const X2: RegisterA64 = reg(KindA64::x, 2);
20const R_CONSTANTS: RegisterA64 = reg(KindA64::x, 23);
21const R_CODE: RegisterA64 = reg(KindA64::x, 24);
22const R_CLOSURE: RegisterA64 = reg(KindA64::x, 25);
23
24fn mem(base: RegisterA64, data: i32) -> AddressA64 {
25 AddressA64 {
26 kind: AddressKindA64::imm,
27 base,
28 offset: RegisterA64::noreg,
29 data,
30 }
31}
32
33pub fn emitContinueCall(build: &mut AssemblyBuilderA64, helpers: &mut ModuleHelpers) {
34 crate::CODEGEN_ASSERT!(CALL_FALLBACK_YIELD == 1);
35
36 build.tbnz(X0, 0, &mut helpers.exitNoContinueVm);
37
38 build.ldr(
39 X1,
40 mem(
41 X0,
42 (core::mem::offset_of!(Closure, inner) + core::mem::offset_of!(LClosure, p)) as i32,
43 ),
44 );
45
46 build.ldr(X2, mem(X1, core::mem::offset_of!(Proto, exectarget) as i32));
47 build.cbz(X2, &mut helpers.exitContinueVm);
48
49 build.mov_register_a_64_register_a_64(R_CLOSURE, X0);
50 build.ldp(
51 R_CONSTANTS,
52 R_CODE,
53 mem(X1, core::mem::offset_of!(Proto, k) as i32),
54 );
55 build.br(X2);
56}