MCPcopy Create free account
hub / github.com/D7EAD/mkPIVM / emit_range_entry

Method emit_range_entry

src/vm_codegen.cpp:668–770  ·  view source on GitHub ↗

--ranges hybrid mode entry stub

Source from the content-addressed store, hash-verified

666
667 // --ranges hybrid mode entry stub
668 void VMCodeGen::emit_range_entry(X64Emitter& e, std::uint32_t bytecode_offset,
669 std::size_t data_island_size,
670 std::uint32_t block_table_count) {
671 const auto& cfg = vm_.dispatcher_regs();
672 const auto& st = vm_.state_layout();
673
674 emit_prologue(e, data_island_size);
675
676 // frame size has to match what emit_prologue computed.
677 const std::uint32_t frame_size = static_cast<std::uint32_t>(vm_.state_layout().total_size) + vm_.shadow_stack_bytes() + vm_.frame_padding();
678 const std::uint32_t aligned_frame = (frame_size + 15) & ~15u;
679
680 // host volatile GPRs into VM slots
681 auto write_slot = [&](XReg xr, std::uint8_t host_reg) {
682 e.mov_mem_reg(
683 cfg.state_ptr,
684 static_cast<std::int32_t>(st.regs_base + vm_.slot_of_xreg(xr) * 8),
685 host_reg,
686 true
687 );
688 };
689
690 write_slot(XReg::AX, rx::rax);
691 write_slot(XReg::CX, rx::rcx);
692 write_slot(XReg::DX, rx::rdx);
693 write_slot(XReg::R8, rx::r8);
694 write_slot(XReg::R9, rx::r9);
695 write_slot(XReg::R10, rx::r10);
696 write_slot(XReg::R11, rx::r11);
697
698 // saved NV regs from the host stack into VM slots
699 auto it = g_prologue_orders.find(&e);
700 if (it == g_prologue_orders.end()) throw Error("emit_range_entry: missing prologue order");
701
702 auto host_to_xreg = [](std::uint8_t r) -> XReg {
703 if (r == rx::rbx) return XReg::BX;
704 if (r == rx::rbp) return XReg::BP;
705 if (r == rx::rdi) return XReg::DI;
706 if (r == rx::rsi) return XReg::SI;
707 if (r == rx::r12) return XReg::R12;
708 if (r == rx::r13) return XReg::R13;
709 if (r == rx::r14) return XReg::R14;
710 if (r == rx::r15) return XReg::R15;
711 return XReg::Invalid;
712 };
713
714 for (std::size_t i = 0; i < it->second.order.size(); ++i) {
715 const std::uint8_t nv_reg = it->second.order[i];
716 const XReg xr = host_to_xreg(nv_reg);
717 if (xr == XReg::Invalid) throw Error("emit_range_entry: unmapped NV reg in prologue order");
718 const std::int32_t stack_off = static_cast<std::int32_t>(aligned_frame) + 64 - 8 * static_cast<std::int32_t>(i);
719
720 e.mov_reg_mem(
721 rx::rax,
722 rx::rsp,
723 stack_off,
724 true
725 );

Callers

nothing calls this directly

Calls 14

ErrorClass · 0.85
shadow_stack_bytesMethod · 0.80
frame_paddingMethod · 0.80
slot_of_xregMethod · 0.80
findMethod · 0.80
endMethod · 0.80
coro_preloMethod · 0.80
emit_dispatch_tailFunction · 0.70
mov_mem_regMethod · 0.45
sizeMethod · 0.45
mov_reg_memMethod · 0.45
lea_reg_memMethod · 0.45

Tested by

no test coverage detected