29 lines
1.3 KiB
Python
29 lines
1.3 KiB
Python
from __future__ import annotations
|
|
from typing import TYPE_CHECKING
|
|
import llvmlite.ir as ir
|
|
if TYPE_CHECKING:
|
|
from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin
|
|
|
|
|
|
def EmitRawCopyLlvm(DstPtr: ir.Value, SrcPtr: ir.Value, Gen: LlvmGeneratorMixin,
|
|
NamePrefix: str = "rawcopy") -> bool:
|
|
"""Emit `*dst = *src` as a raw byte copy (Load semantics); False if unusable.
|
|
|
|
The width comes from the destination pointee and the source pointer is
|
|
bitcast to it, so this reinterprets memory instead of converting values
|
|
(e.g. `*&bits = *&dbl` must keep the IEEE bits, not fptosi).
|
|
"""
|
|
if not isinstance(DstPtr.type, ir.PointerType) or not isinstance(SrcPtr.type, ir.PointerType):
|
|
return False
|
|
Pointee: ir.Type = DstPtr.type.pointee
|
|
if isinstance(Pointee, ir.VoidType):
|
|
return False
|
|
TargetPtrTy: ir.PointerType = ir.PointerType(Pointee)
|
|
SrcCast: ir.Value = SrcPtr if SrcPtr.type == TargetPtrTy else Gen.builder.bitcast(SrcPtr, TargetPtrTy, name=f"{NamePrefix}_src_cast")
|
|
Loaded: ir.Value | None = Gen._load(SrcCast, name=f"{NamePrefix}_loaded")
|
|
if Loaded is None:
|
|
return False
|
|
DstCast: ir.Value = DstPtr if DstPtr.type == TargetPtrTy else Gen.builder.bitcast(DstPtr, TargetPtrTy, name=f"{NamePrefix}_dst_cast")
|
|
Gen._store(Loaded, DstCast)
|
|
return True
|