A method of accelerating program execution across instruction set architecture emulation

CN121934891BActive Publication Date: 2026-08-21SUN YAT SEN UNIV
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202610398741.2
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2026-03-30
Publication Date
2026-08-21
Estimated Expiration
2046-03-30

AI Technical Summary

Technical Problem

由于不同ISA在指令集、寄存器、内存模型等方面存在根本性差异,这种翻译过程通常会导致显著的性能损失

Benefits of technology

[0047]1.本发明显著提升执行性能,克服传统翻译瓶颈。本发明通过利用高级语言源代码的指令集架构(ISA)无关性,在编译阶段将客体程序的函数语义分离,并在运行阶段将其调用直接转发至预编译的、宿主ISA的高效原生代码执行,从而彻底避免了动态二进制翻译技术中逐条指令进行低效翻译与模拟的巨大开销。因此,该方法能够大幅提升跨ISA运行程序的速度和效率,根据程序中可分离函数所占的计算比重,通常可获得数倍至数十倍的性能加速。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN121934891B_ABST
    Figure CN121934891B_ABST
Patent Text Reader

Abstract

The application discloses a method for accelerating cross instruction set architecture simulation execution of a program, comprising the following steps: S1, in a compiling stage, generating an independent host side intermediate code file; meanwhile, generating a stub function same as a function signature in an original translation unit; S2, in a linking stage, generating a host code module corresponding to an original linking result file one by one according to a linking process of an original program and based on the host side target file, and generating module level data for each host code module; S3, summarizing all the host code modules to form a unified host program library; S4, based on the host program library, generating a stub module working at a guest side corresponding to the guest linking result one by one; S5, forwarding a guest side function call to a host side equivalent function execution, and returning to the guest side to continue execution after the execution is completed. The application bypasses inefficient instruction level binary translation, and realizes fundamental improvement of cross instruction set architecture simulation execution performance.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention relates to the field of computer software, specifically to a method for accelerating the simulated execution of programs across instruction set architectures. Background Technology

[0002] Instruction Set Architecture (ISA) is a specification of a set of instructions that a computer's central processing unit (CPU) understands and executes. It defines the basic interface between software and hardware. Since the introduction of the IBM System / 360 in 1964, ISA has been the core of computer architecture. CPUs designed by different manufacturers typically use different ISAs, such as x86, ARM, and RISC-V. Because software programs must ultimately be compiled into machine code supported by the target CPU's ISA to execute, the differences in ISAs have fundamentally led to a fragmented software ecosystem, forming independent ecosystems centered around each hardware platform. Among them, the x86 architecture, with its deep historical accumulation and vast software library, has long dominated the personal computer and server market.

[0003] With the slowdown in semiconductor process advancements (Moore's Law slowing) and the rise of emerging ISAs (such as ARM and RISC-V), the demand for running programs compiled for one processor architecture (ISA) on one processor—i.e., cross-ISA emulation—is growing. This technology is of critical strategic importance for emerging ISA platforms to maintain compatibility with existing massive amounts of software, attract existing users, and expand market share. Several application examples have emerged in industry practice. For instance, Apple developed the Rosetta 1 and Rosetta 2 emulation engines during its migration from PowerPC to x86 and from x86 to ARM architectures, respectively; Microsoft developed the Prism engine for the Windows on ARM platform to support x86 applications; Huawei provided the ExaGear emulator for its ARM processors to ensure compatibility with x86 programs; and Loongson Technology added binary translation hardware support to its LoongArch instruction set for efficient execution of x86 programs.

[0004] Currently, the mainstream technology for cross-ISA program emulation is binary translation. This technology, through pure software or a combination of software and hardware, simulates the runtime environment of an "object" ISA (such as x86) on the hardware platform of the "host" ISA (such as an ARM CPU). Its core process involves dynamically or statically translating each machine instruction of the object program into one or more semantically equivalent instruction sequences on the host ISA, and then interpreting and executing them. Due to fundamental differences in instruction sets, registers, and memory models among different ISAs, this translation process typically leads to significant performance losses. A single object instruction often requires a combination of multiple host instructions for emulation, resulting in enormous overhead. Practice shows that a purely software-implemented binary translation system is typically an order of magnitude (more than ten times) slower than direct execution on native hardware; even with dedicated hardware acceleration modules, its performance often falls short of 80% of native performance and is limited by specific chip designs. Therefore, low performance has become a prominent bottleneck restricting the widespread application of cross-ISA emulation technology and a major technological barrier hindering the integration of different computing ecosystems.

[0005] However, it should be noted that the aforementioned severe performance issues primarily exist in scenarios involving the low-level instruction translation of compiled "binary programs." In modern software development practice, the vast majority of programs are written in high-level languages ​​such as C / C++, rather than directly using assembly language specific to a particular ISA. The same high-level language source code can generate binary programs for different platforms using compilers designed for different ISAs. Although these binary programs differ greatly at the machine code level, their underlying functional logic and algorithms are highly consistent or homogeneous at the high-level language level. Therefore, if this homogeneity of programs at the high-level language level can be utilized to avoid or reduce inefficient translation at the low-level binary instruction level, it may be possible to overcome the performance bottleneck of existing binary translation and achieve more efficient cross-ISA program execution. Summary of the Invention

[0006] To overcome the shortcomings of the prior art, the present invention aims to provide a method for accelerating the simulated execution of programs across instruction set architectures. This method separates and pre-compiles the object program functions into host-side equivalent code during the program construction phase, and directly schedules and executes the equivalent code at runtime through mechanisms such as stub functions and call conversion, thereby bypassing inefficient instruction-level binary translation and achieving a fundamental improvement in the performance of simulated execution across instruction set architectures.

[0007] To achieve the above objectives, the following solution is adopted:

[0008] A method for accelerating the emulation of programs across instruction set architectures includes the following steps:

[0009] S1: During the compilation phase, for programs written in high-level languages ​​and running on the object side, functions that meet predetermined conditions in each translation unit are separated to generate independent host-side intermediate code files, and the intermediate code files are compiled into host-side object files; at the same time, stub functions with the same signature as the functions are generated in the original translation unit.

[0010] S2: During the linking phase, based on the linking process of the original program and the target file on the host side, host code modules corresponding one-to-one with the original linking result files are generated, and module-level data is generated for each host code module.

[0011] S3: Aggregate all host code modules to form a unified host program library, and assign unique consecutive integer identifiers to all object functions in the host program library;

[0012] S4: Based on the host program library, generate a stub module that corresponds one-to-one with the object linking result and works on the object side. The stub module is used to complete the missing function identifiers in the object linking result.

[0013] S5: During program execution, the stub functions, stub modules, and host program libraries are used to forward object-side function calls to equivalent host-side functions for execution through call conversion, interpretation reentrancy, and data layout adaptation mechanisms. After execution is completed, the program returns to the object side to continue execution.

[0014] Furthermore, the call conversion includes the following steps:

[0015] Parameter conversion: Retrieve parameters from the simulator's virtual registers and the object call stack according to the object application's binary interface, and then rearrange them into the host-side registers and call stack according to the host application's binary interface;

[0016] Call triggering: Switching control flow from the object side to the host side through predefined cross-architecture call instructions or system calls;

[0017] Return value conversion: Retrieve the return value data from the host side's registers and call stack according to the host application's binary interface, and then rearrange it into the simulator's data structure and the object's call stack according to the object application's binary interface.

[0018] Furthermore, the call conversion step also includes:

[0019] In the stub function, collect pointers or addresses of all external symbols involved in the delimited function body and store them in a parameter structure;

[0020] When the call is triggered, the parameter structure is passed to the host-side equivalent function;

[0021] The host-side equivalent function accesses data in the object's address space through pointers or addresses in the parameter structure.

[0022] Furthermore, the interpretation reentrancy includes the following steps:

[0023] Before the object-side stub function triggers a cross-architecture call, a memory area is reserved on the object call stack to accommodate the host-side equivalent function stack frame and the host-side execution context;

[0024] When a cross-architecture call is triggered, the simulator saves the address of the next instruction of the object program to the object call stack, creates a stack frame for the host-side equivalent function in the reserved memory area, and switches the control flow to the execution of the host-side equivalent function;

[0025] When the host-side equivalent function needs to call back the object-side function, the callback mechanism is triggered to enter the callback stub function on the object side;

[0026] The callback stub function retrieves parameters from the host-side stack frame, calls the specified object-side function, collects the return value to the host-side stack frame after the object-side function has finished executing, and then switches back to the host side to continue execution.

[0027] Furthermore, the data layout adaptation includes the following steps:

[0028] When separating object functions into host-side intermediate code, traverse and identify instructions that are affected by the differences in binary interface data layout between the object and the host application;

[0029] Replace the affected instructions with calls to predefined, architecture-independent primitive functions;

[0030] The primitive functions are marked as inline functions to eliminate calling overhead and allow compiler optimization.

[0031] Furthermore, it also includes a first optimization step:

[0032] When the object function body contains code that cannot be directly compiled on the host side, the code portion bound to the object architecture will be externalized into an independent object-side function;

[0033] In the host-side equivalent function, the external object-side function is called through a callback mechanism.

[0034] Furthermore, it also includes a second optimization step:

[0035] When the program is loaded or the dynamic library is initialized, a global reference table is constructed for each host code module. The global reference table contains the addresses of all external symbols involved in the functions of the module.

[0036] When the conversion is invoked, the pointer to the global reference table is directly passed to the host-side equivalent function to avoid dynamic construction on each call.

[0037] Furthermore, it also includes a third optimization step:

[0038] When two object functions that have been separated to the host side need to call each other, the function call is made directly on the host side without going through the callback mechanism of switching between host and object;

[0039] Before triggering cross-architecture calls, the object-side stub function needs to reserve a sufficiently large stack space on the object call stack to accommodate possible multi-level nested calls on the host side.

[0040] Furthermore, it also includes a fourth optimization step:

[0041] When the program starts or the dynamic library is loaded, a dynamic callback forwarding table is constructed. The dynamic callback forwarding table records the mapping of all object-side function addresses to their corresponding host-side equivalent function addresses.

[0042] Each time a function call occurs, the dynamic callback forwarding table is first queried. If an equivalent function on the host side is found, it is called directly; otherwise, the object side function is called through the callback mechanism.

[0043] Furthermore, it also includes a fifth optimization step:

[0044] During the linking phase, instead of generating a separate unified host library, each host code module is directly embedded into its corresponding object linking result file.

[0045] When a cross-architecture call occurs, the host side uses the entry address of the object function for offset addressing, directly locates and executes the embedded host-side equivalent function code.

[0046] Compared with the prior art, the beneficial effects of the present invention are as follows:

[0047] 1. This invention significantly improves execution performance and overcomes the bottlenecks of traditional translation. By leveraging the instruction set architecture (ISA) independence of high-level language source code, this invention separates the function semantics of the object program during the compilation phase and directly forwards its calls to the pre-compiled, highly efficient native code of the host ISA during runtime. This completely avoids the enormous overhead of inefficient instruction-by-instruction translation and simulation in dynamic binary translation technology. Therefore, this method can significantly improve the speed and efficiency of running programs across ISAs, typically achieving performance acceleration of several to tens of times, depending on the computational proportion of separable functions in the program.

[0048] 2. This invention is compatible with closed-source programs, achieving partial acceleration. For closed-source programs (especially dynamically linked programs) that only exist in binary form, this invention has the capability for partial application. Although the main program cannot directly process these functions, it can implement the entire process for the open-source underlying dynamic libraries that it depends on, which have source code. During program runtime, the closed-source program's calls to these library functions can be seamlessly forwarded to the accelerated version on the host side for execution through the generated stub functions and stub modules. This allows for an overall performance improvement of several to tens of times by accelerating the calls to its key library functions, even if the main program still needs to be interpreted and executed.

[0049] 3. This invention supports quasi-cross-platform build and execution with zero source code modification. For programs with complete source code but containing platform-specific code (such as inline assembly), this invention provides an efficient quasi-cross-platform solution. The predetermined conditions of this invention provide flexibility for handling code that cannot be directly separated (e.g., through external optimization). This method allows the main program structure to remain the original ISA (maintaining the ABI interface through stub functions), while separating and compiling most of the portable code into an efficient equivalent form of the target ISA. Therefore, "zero-modification" compilation and build can be achieved without modifying the source code to adapt to the target ISA, ensuring performance close to true cross-platform native compilation during cross-ISA simulation execution. Attached Figure Description

[0050] Figure 1 This is a schematic diagram illustrating the compilation, building, and execution process of a C / C++ program as described in Background 1 of this invention.

[0051] Figure 2 This is a schematic diagram illustrating the function call and return process in Background 2 of this invention;

[0052] Figure 3 This is a schematic diagram of the dynamic binary translation system described in Background 4 of this invention;

[0053] Figure 4 This is a flowchart of a method for accelerating the simulated execution of programs across instruction set architectures in an embodiment of the present invention;

[0054] Figure 5 This is a schematic diagram illustrating the workflow of the gyhcall compilation acceleration method in an embodiment of the present invention;

[0055] Figure 6 This is a schematic diagram of the function interfaces involved in the conversion process in an embodiment of the present invention;

[0056] Figure 7 This is a schematic diagram illustrating the reentrant object stack frame structure in an embodiment of the present invention;

[0057] Figure 8This is a schematic diagram illustrating the call transformation after applying optimizations 2 and 3 in an embodiment of the present invention;

[0058] Figure 9 This is a schematic diagram of the overall process after applying optimization 5 in an embodiment of the present invention. Detailed Implementation

[0059] The present invention will now be further described in conjunction with the accompanying drawings and specific embodiments. It should be noted that, without conflict, the various embodiments or technical features described below can be arbitrarily combined to form new embodiments.

[0060] First, the technical background necessary for explaining the embodiments of the present invention will be introduced. It should be noted that the embodiments of the present invention are described based on the C / C++ programming language and ELF binary program format on the Linux operating system, but the present invention is not limited thereto. The core technical principles of the present invention can be fully transferred to other compiled programming languages ​​and other binary program formats on other operating systems such as Windows and MacOS.

[0061] Background 1: The compilation and building process from high-level language source code to binary programs

[0062] like Figure 1 The diagram illustrates the complete process of compiling, linking, loading, and executing a program written in the high-level C / C++ language. The compilation stage generates object files (usually ending with the .o file extension) from the source code files. These object files contain binary machine code semantically equivalent to the source code in the high-level language—note that a single source file may generate multiple object files depending on different compilation parameters (e.g., ...). Figure 1 The source code files (.cc files) being converted into object files are called "translation units." The linking process merges and aggregates the binary code from multiple object files, filling in the mutual references in the original object file's binary code based on the aggregation result, forming the final program file—note that one object file may also be integrated into multiple final program files, resulting in two different sets of code. The resulting program files can be categorized into two types: statically linked and dynamically linked. The former contains the complete code required by the program and can be directly loaded and executed (e.g., a.out); the latter typically contains only program-specific code, while placing some common code used by the program in external dynamic link libraries (usually ending with a .so suffix), thus requiring these external files to be loaded during runtime (e.g., c.out and b.so).

[0063] The compilation process from high-level languages ​​to binary is a transformation of program code. For simplicity, the basic unit of program code can be considered a "function" (also called a sub-procedure)—that is, the contents of the various file types mentioned above can be considered as functions, and the transformation process is the processing of these content functions. The final process involves multiple sets of functions from different translation units. Compared to static linking, dynamic linking can separate common functions into separate program files, thus significantly reducing the overall size of multiple programs combined. Modern computer software systems typically contain a large number of applications; therefore, in practice, the vast majority of applications are dynamically linked.

[0064] Background 2: Function Call Process

[0065] like Figure 2 The diagram illustrates the state transition of a running process when a function call is triggered. The main structure of the control state of a running process is the call stack, which is composed of stacked stack frames, interspersed with each other. Each stack frame is associated with a function in the program code. When a function call is triggered, the process creates the corresponding function's stack frame on the call stack, as well as a swap space for parameter passing and return value retrieval. Figure 2 (Middle gray area). Next, the process will enter the code of the function corresponding to the new stack frame and execute until the code of the called function has finished executing. When the called function returns, it puts the return value data into the swap area, and then pops its corresponding stack frame, restoring the process control flow to the state before the call and continuing to execute the previous stack frame.

[0066] It must be pointed out that, generally speaking, the only connection between the called function and the calling function is the swap area between stack frames—as long as the data in the swap area between stack frames is the same, then no matter how the called function executes, it will not affect the functionality and behavior of the calling function. In program code, this means that as long as the parameters and return value of the called function are the same, it doesn't matter to the caller how the called function is implemented; the caller can work in the same way. This relative independence between the called function and the calling function provides an opportunity for the acceleration method of this invention.

[0067] Background 3: ABI and Dynamic Link Libraries

[0068] During the compilation process from high-level languages ​​to binary machine code, functions in the high-level language are converted into equivalent machine instruction sequences, and types in the high-level language are deconstructed into binary-level byte data layouts. The specification regarding how binary-level functions call each other is called the Application Binary Interface (ABI). As mentioned earlier, the inter-frame swap area is usually the only connection point between the function caller and the callee, and how data is laid out in this swap area is naturally part of the ABI definition. The ABI standard defines how function parameters and return values ​​are passed, for example: in which CPU registers, or on the call stack; if on the call stack, in what order; and so on. Naturally, the specific content of the ABI standard depends on the CPU ISA, and the ABI standards of different ISAs are completely different—this means that when executing programs across ISAs, the differences between ABIs must be resolved.

[0069] As mentioned at the beginning, most programs are generated using dynamic linking. For these programs, the code required for their operation is scattered across other binary files (called dynamic link libraries). At this point, the Application Interface (ABI) becomes extremely important—if the ABI of a dynamic link library doesn't match the application's, the application will almost certainly fail to function correctly. On the other hand, it's also clear that the ABI is very stable—because modifying it involves changes to all existing dynamic link libraries, which is almost impossible to do within a mature ISA software system. In fact, dynamic link libraries are designed to leverage the stability of the ABI, allowing for partial updates to program code without altering other program files, thereby fixing bugs or adjusting functionality. Therefore, the independence between the called function and the invoked function is naturally reflected at the dynamic link library level. As long as the ABI and semantic behavior of the dynamic link library are consistent, more efficient implementations can replace inefficient library files, thus accelerating program execution. Moreover, this method has extremely high compatibility and reliability, as this is one of the original design purposes of dynamic link libraries.

[0070] Background 4: Dynamic Binary Translation

[0071] Software or a combination of hardware and software dynamic binary translation systems are currently the main method for emulating program execution across ISAs, such as... Figure 3 As shown, Figure 3This is an illustration of such a system. During simulation, the simulator first starts on the host system, then loads the object program, and executes it from the program entry point according to the object program's semantics. During execution, whenever a new piece of object code is encountered, the simulator first translates it into semantically equivalent code on the host system, and then executes that equivalent code. Therefore, the simulator creates the object program's call stack and manipulates its memory space in the same way as when the object program executes directly. Of course, as a program working on the host system, the simulator also has its own call stack. All behaviors of the object program are monitored by the simulator. If the object program needs to access a lower-level system, for example, if a system call occurs, the code that triggers the system call is first captured by the simulator and then translated into an equivalent system call on the host system. Therefore, there are various ways to inject new translation mechanisms into the object program, such as adding special instructions that do not exist in the object's ISA, or creating system call numbers that do not exist in the host system. These methods can be used to achieve accelerated execution switching between the object and the host.

[0072] like Figure 4 As shown, the present invention provides a method for accelerating the simulated execution of programs across instruction set architectures, comprising the following steps:

[0073] S1: During the compilation phase, for programs written in high-level languages ​​and running on the object side, functions that meet predetermined conditions in each translation unit are separated to generate independent host-side intermediate code files, and the intermediate code files are compiled into host-side object files; at the same time, stub functions with the same signature as the functions are generated in the original translation unit.

[0074] like Figure 5 The overall workflow of this invention is illustrated below. This invention refers to the method as "gyhcall". (Observation) Figure 1 and Figure 5 As can be seen, the main structures of the two diagrams are largely the same, which indicates that gyhcall is compatible with the current program's compilation and build process, thus possessing strong practical value. The overall workflow is described in detail below:

[0075] During the compilation phase, gyhcall separates functions that meet certain conditions from each translation unit, generating independent intermediate code files for each translation unit (called gyhlib units). It also leaves "stub" functions in the original translation unit that have the same signature as the original function (i.e., function name, parameters, return type, and other interface information). Subsequently, gyhlib is compiled into a binary program for the host ISA and executed directly on the host system. The function body of the stub is simply a forwarding operation to the equivalent function in the gyhlib unit. As mentioned earlier, there are ABI differences between the object program and the host system, therefore call translation is necessary.

[0076] S2: During the linking phase, based on the linking process of the original program and the target files on the host side, host code modules corresponding one-to-one with the original linking result files are generated, and module-level data is generated for each host code module.

[0077] During the linking phase, gyhcall follows the original program's linking process to generate "gyhlib modules" that correspond one-to-one with the original linking result files. In this stage, some additional module-level data is generated into the gyhlib modules to support subsequent execution.

[0078] S3: Aggregate all host code modules to form a unified host program library, and assign unique consecutive integer identifiers to all object functions in the host program library.

[0079] In this invention, the generated gyhlib modules are aggregated into a unified "gyhlib," a large library containing the equivalent code of all object functions on the host machine, used during simulator execution. In this step, a unique identifier (ID) needs to be assigned to each object function. This ID is passed to the simulator by the object when acceleration is triggered during runtime, and the simulator calls the equivalent host function based on this ID. It is particularly important to note that the IDs are consecutively assigned integers, allowing the host side to directly and quickly address the equivalent function using array indices. This significantly reduces the overhead of calls—crucial for frequently called object functions.

[0080] S4: Based on the host program library, generate stub modules that correspond one-to-one with the object linking results and work on the object side. The stub modules are used to complete the missing function identifiers in the object linking results.

[0081] This invention generates "gyhlib stub modules" that correspond one-to-one with the object linking results and operate on the object side. The stub modules complete the missing function IDs and other information in the object linking results. Depending on whether the program is statically or dynamically linked, the stub module may be a relocatable object file (.o) or a dynamic link library file (.so). For statically linked programs, the stub module needs to be linked into the object program during the build process.

[0082] S5: During program execution, the stub functions, stub modules, and host program libraries are used to forward object-side function calls to equivalent host-side functions for execution through call conversion, interpretation reentrancy, and data layout adaptation mechanisms. After execution is completed, the program returns to the object side to continue execution.

[0083] For dynamically linked object programs, the gyhlib stub module can be deferred until it is automatically loaded at startup. Therefore, the gyhcall method is completely unaffected by the dynamic linking process, making it highly practical.

[0084] To enable gyhlib to work collaboratively between the host and object code sides, this invention solves three core technical challenges: call conversion, interpretation reentrancy, and data layout adaptation. Furthermore, to ensure that gyhcall truly delivers execution performance far exceeding that of ordinary binary dynamic translation, various optimization techniques are essential. These techniques are detailed below.

[0085] Furthermore, the call conversion includes the following steps:

[0086] Parameter conversion: Retrieve parameters from the simulator's virtual registers and the object call stack according to the object application's binary interface, and then rearrange them into the host-side registers and call stack according to the host application's binary interface;

[0087] Call triggering: Switching control flow from the object side to the host side through predefined cross-architecture call instructions or system calls;

[0088] Return value conversion: Retrieve the return value data from the host side's registers and call stack according to the host application's binary interface, and then rearrange it into the simulator's data structure and the object's call stack according to the object application's binary interface.

[0089] Regarding the invocation of conversion technology, the specific details are as follows:

[0090] Call translation technology, implemented by gyhcall to accelerate function calls, switches between the object ABI and the host ABI. The call translation process consists of three parts: parameter conversion, call triggering, and return value conversion. Furthermore, the issue of external symbols referenced by the called function must also be addressed.

[0091] Parameter conversion transforms the parameters of an object function call into the form of a host function call. Specifically, the ABI typically specifies that the first few parameters of a function are passed through registers, while more parameters are passed through the call stack. The registers of the object ABI do not exist during simulated execution but are represented as structure fields in the simulator. Therefore, parameter conversion needs to retrieve parameter values ​​from the virtual registers and the object call stack sequentially according to the ABI standard, and then place them on the host machine according to the host ABI standard. This process can be implemented in two ways: First, the host and object work together—the parameters are first arranged in the call stack memory in the stub generated during the compilation stage (①) according to the ISA-independent standard form, and then the parameters are retrieved from the call stack on the host side and placed into the host machine's registers and call stack; Second, it is done entirely on the host side—in the simulator, the parameters are directly retrieved from the fields of the relevant structure and placed into the corresponding host machine registers and call stack.

[0092] The call can be triggered by special ISA instructions or special system calls, which are referred to in this invention as the GYHCALL instruction and the gyhcall system call. The specific machine code format of the GYHCALL instruction depends on the object ISA. For example, the opcode of the GYHCALL instruction on the x86 ISA is defined as 0F-0F-09-06, while the gyhcall system call number on Linux is defined as 50906.

[0093] Return value conversion is similar to parameter conversion, except that it involves retrieving the relevant data from the host-side registers and call stack and rearranging it onto the object data structure and call stack. It can also be implemented using either a host-object cooperative approach or a completely host-side approach. After the equivalent function on the host side completes execution, gyhcallret is triggered to switch back to the object side to continue the simulation execution.

[0094] Furthermore, the call conversion step also includes:

[0095] In the stub function, collect pointers or addresses of all external symbols involved in the delimited function body and store them in a parameter structure;

[0096] When the call is triggered, the parameter structure is passed to the host-side equivalent function;

[0097] The host-side equivalent function accesses data in the object's address space through pointers or addresses in the parameter structure.

[0098] The called function may use symbols defined outside the function body, such as global variables and other functions. Taking global variables as an example, their definition is within the object's address space, not the host's. Therefore, if the object code is directly separated and executed on the host side, an error will occur indicating that the external reference symbol cannot be found. To address this, gyhcall transforms the function body's code during object function separation, turning external references into function parameters. Specifically, gyhcall collects all external symbols involved in the function body within the object's stub function, stores their pointers / addresses in a parameter structure, and passes this parameter structure to the host function when the call is triggered. The host function accesses the object's memory space by adding an offset to the obtained pointer / address, ensuring that the host function executes semantics equivalent to the object. Furthermore, the separated function may call other external functions, which is more complex and requires the assistance of object-side callback stubs.

[0099] like Figure 6 The diagram illustrates a stub function after function separation, a host-side equivalent function, and its matching callback stub interface. Compared to the stub function, the host-side equivalent function transforms the original parameters and return values ​​into structures, which are passed as pointers via the first and second parameters, respectively. It also includes two additional pointer parameters: the external reference table involved in the function body and the callback stub table. The contents of these two pointer tables are filled by the stub function working on the object side and passed into the host side.

[0100] Furthermore, the interpretation reentrancy includes the following steps:

[0101] Before the object-side stub function triggers a cross-architecture call, a memory area is reserved on the object call stack to accommodate the host-side equivalent function stack frame and the host-side execution context;

[0102] When a cross-architecture call is triggered, the simulator saves the address of the next instruction of the object program to the object call stack, creates a stack frame for the host-side equivalent function in the reserved memory area, and switches the control flow to the execution of the host-side equivalent function;

[0103] When the host-side equivalent function needs to call back the object-side function, the callback mechanism is triggered to enter the callback stub function on the object side;

[0104] The callback stub function retrieves parameters from the host-side stack frame, calls the specified object-side function, collects the return value to the host-side stack frame after the object-side function has finished executing, and then switches back to the host side to continue execution.

[0105] The specific details regarding the explanation of reentrancy technology are as follows:

[0106] This invention explains how reentrancy addresses the issue of host-side equivalent functions calling back to object-side functions, which then trigger host-side calls again. To explain this, it's important to first point out that binary translation typically occurs on the simulator's call stack. When `gyhcall` is triggered, the process switches to the simulator's call stack for execution. While the host-side equivalent function can be directly called at this point, this is incorrect. Instead, it must run on the object call stack, whose data layout conforms to the object program's ABI standard. This is because non-local control flows—such as `setjump` / `longjump` and exception control flows—may exist within the program. These control flows traverse multiple stack frames. If these stack frames are not placed on the object call stack, they may not be released during non-local control flows, leading to residue and leaks.

[0107] gyhcall proposes two design features to address this issue: First, before triggering the gyhcall call in the object-side stub function, the stub function allocates a memory region on the object call stack large enough to accommodate the host-side equivalent function's stack frame and the host-side execution context (ucontext_t). Then, when the gyhcall call is triggered, the simulator saves the address of the next instruction of the current object program to the object call stack, creates a stack frame (makecontext) for the corresponding host-side equivalent function on the object call stack, and switches the control flow (swapcontext). In this way, the host-side equivalent function executes on the object call stack.

[0108] To switch between execution from the host function and the object function, a "callback stub" operating on the object side is necessary. The callback stub is generated based on the signatures of all function calls within the host-side equivalent function. For example, if the body of a host-side equivalent function contains a function call `int x = foo(1, 2)`, its corresponding function call signature is `intfoo(int, int)`. Therefore, a `void __gyh_call_back_xxx(void ... )` will be generated on the object side. void void The callback stub. The callback stub is... Figure 5 The compilation phase (①) generates a gyhlib translation unit, so duplication is inevitable. To remove duplicates, the xxx in the callback stub name is a hash value calculated based on the signature type (parameters and return value), and all callback stubs are generated as weakly symbolic functions (such functions will only have one copy when name conflicts occur during the linking phase).

[0109] like Figure 7The diagram illustrates the call stack structure of an accelerated object function `foo` calling back another object function `bar`. Looking from left to right, first, on the object side, the stub function left by `foo` is called. Within the stub function, the return value `x` and parameters 1 and 2 are neatly arranged on the stack. Then, `gyhcall` is triggered. The simulator saves the object program pointer on the call stack, aligns the stack to the host ABI requirements, creates a stack frame for the equivalent function of `foo`, and executes it. When the host-side equivalent function needs to call `bar`, it places the neatly arranged parameters, return value, and call context on the call stack, then triggers `gyhcallback` to enter the simulator's object side to call the `__gyh_call_back_xxx` callback stub, passing in the pointer to `bar`. The callback stub retrieves the parameters from the host-side equivalent function's stack frame, calls the passed function pointer, and the program enters the object-side `bar` function to continue simulation execution. After the `bar` function finishes execution, the callback stub collects the return value into the receiving area of ​​the equivalent function's stack frame, then triggers `gyhcallbackret` to return to the call point of the host-side equivalent function and continue execution. Finally, when the equivalent function of `foo` finishes executing, `gyhcallret` is triggered, switching execution back from the host side to the object side. The stub function of `foo` creates a sufficiently large region on the stack frame to accommodate the stack frame of the equivalent function. Therefore, the stack frame of the equivalent function of `foo` is actually embedded within the stack frame of the object `foo`. Thus, from the object's perspective, the stack frame structure is `foo->__gyh_call_back_xxx->bar`. As mentioned earlier, the internal structure of the stack frame is invisible to the outside world; therefore, this stack frame structure is fully compatible with the object's ABI definition and can fully support `setjump / longjump`, exceptions, and even stack backtracking.

[0110] Furthermore, the data layout adaptation includes the following steps:

[0111] When separating object functions into host-side intermediate code, traverse and identify instructions that are affected by the differences in binary interface data layout between the object and the host application;

[0112] Replace the affected instructions with calls to predefined, architecture-independent primitive functions;

[0113] The primitive functions are marked as inline functions to eliminate calling overhead and allow compiler optimization.

[0114] The specific details regarding data layout adaptation technology are as follows:

[0115] Data layout adaptation techniques are used to address layout differences between data structures on the object and host ABIs. For example, a `long` type is 4 bytes on a 32-bit machine but 8 bytes on a 64-bit machine. Handling these layout differences is crucial for the correct operation of gyhcalls—because the code separated to the host side operates on the object data during execution. Generally, when the separated code is compiled directly to the host-side target, it operates on data according to the host-side ABI data structure layout, which may incorrectly modify memory and cause runtime errors.

[0116] To address this issue, gyhcall iterates through and modifies all affected data operations while separating the host-side equivalent functions. Specifically, it first implements compiler-built-in primitive functions on atomic data types where the host is the object, and then replaces the relevant operation instructions in the code with calls to these primitives. Note that all built-in primitive functions are marked as always inline, thus eliminating function call overhead and enabling compiler backend optimizations.

[0117] By employing three techniques—call conversion, interpretation reentrancy, and data layout adaptation—this invention ensures that the functions separated from the host side by gyhcall are semantically completely equivalent to the simulated execution of the client program, thereby guaranteeing the correctness of program execution. However, relying solely on these three techniques is insufficient to maximize the efficiency of host-side execution; therefore, the following optimization techniques are equally important.

[0118] Furthermore, the method for accelerators to simulate execution across instruction set architectures also includes a first optimization step:

[0119] When the object function body contains code that cannot be directly compiled on the host side, the code portion bound to the object architecture will be externalized into an independent object-side function;

[0120] In the host-side equivalent function, the external object-side function is called through a callback mechanism.

[0121] Optimization 1: Local code external linking, details are as follows:

[0122] There are situations where gyhcall cannot separate an object's function into the host side. For example, if the object function body contains inline assembly code, directly separating this function will fail to compile on the host side. The solution is to outline the portion of the function body bound to the object before separation, making it an independent function outside the original function, and then use the gyhcallback mechanism to call it back on the host side.

[0123] This optimization can greatly broaden the scope of gyhcall and increase the number of separable functions in the program.

[0124] Furthermore, the method for accelerators to simulate execution across instruction set architectures also includes a second optimization step:

[0125] When the program is loaded or the dynamic library is initialized, a global reference table is constructed for each host code module. The global reference table contains the addresses of all external symbols involved in the functions of the module.

[0126] When the conversion is invoked, the pointer to the global reference table is directly passed to the host-side equivalent function to avoid dynamic construction on each call.

[0127] Optimization 2: Global library reference table, details are as follows:

[0128] Note that, Figure 6 In this context, each time a `gyhcall` occurs, the object side must collect all external references and callback stubs involved in the function body into a structure and then pass it to the master side. For complex functions, completing these two tasks can involve a significant number of memory write operations. However, it's also worth noting that all external references remain unchanged throughout the entire runtime after the object side completes program loading. Therefore, it's unnecessary to construct a global reference table for each function call; instead, it can be done in advance during program loading, and then the constructed table pointer can be directly passed during the call.

[0129] It is important to note that the global reference table is specific to the gyhlib module; therefore, a running object process may contain multiple global reference tables due to loading multiple dynamic link libraries. Furthermore, the constructed table pointer does not need to be passed on every call. Instead, it can be registered with the host side once during program startup or dynamic library loading in the entry function (_start) and the dynamic library initialization hooks (.init_array and __attribute__((constructor))). This further reduces the overhead of gyhcall calls.

[0130] Furthermore, the method for accelerators to simulate execution across instruction set architectures also includes a third optimization step:

[0131] When two object functions that have been separated to the host side need to call each other, the function call is made directly on the host side without going through the callback mechanism of switching between host and object;

[0132] Before triggering cross-architecture calls, the object-side stub function needs to reserve a sufficiently large stack space on the object call stack to accommodate possible multi-level nested calls on the host side.

[0133] Optimization 3: Faster path for calls made on the same side of the host machine, details are as follows:

[0134] If both guest functions are separated and moved to the host side, they can call each other without needing to switch between host and guest functions via gyhcallback, saving significant call overhead. However, to achieve this optimization, optimization 2 must first be applied. This is because each function involves different external references, and... Figure 6 In the original call conversion, the object-side stub function only collects its own external references, so the host-side equivalent function cannot construct the external reference table required for further calls to other functions.

[0135] like Figure 8 The diagram shows the call transformation after applying optimization 2 and then optimization 3. Compared to the original call transformation, Figure 8 The host-side equivalent function uses the same signature as the original function to allow direct calls between equivalent functions. The conversion of object parameters and return values ​​to the host side is now handled by the forwarding function, which simply forwards the call to the equivalent function while passing / collecting the normalized parameters / return values. After the global reference table is passed to the host side, it is set to a global variable specific to its gyhlib module, making it accessible to all host-side equivalent functions within the module. Furthermore, when applying optimization 3, the object-side stub function must allocate a sufficiently large stack space on the object call stack before triggering gyhcall—because mutual calls between host-side equivalent functions may create multiple stack frames without notifying the object side, thus consuming an unlimited amount of call stack space.

[0136] Furthermore, the method for accelerators to simulate execution across instruction set architectures also includes a fourth optimization step:

[0137] When the program starts or the dynamic library is loaded, a dynamic callback forwarding table is constructed. The dynamic callback forwarding table records the mapping of all object-side function addresses to their corresponding host-side equivalent function addresses.

[0138] Each time a function call occurs, the dynamic callback forwarding table is first queried. If an equivalent function on the host side is found, it is called directly; otherwise, the object side function is called through the callback mechanism.

[0139] Optimization 4: Dynamic callback forwarding table, details are as follows:

[0140] Optimization 3 only eliminates the host-guest switching overhead for direct calls between host-side functions within the same gyhlib module. It is ineffective for cross-gyhlib module calls and indirect calls (such as calling function pointers). Optimization 3 can be further extended to these scenarios, thereby eliminating host-guest switching overhead in almost all call cases. Specifically, a dynamic callback forwarding table is used. This table contains a mapping of all object-side function addresses to their host-side function addresses, constructed by traversing the global reference table when the object program starts or the dynamic library is loaded. Then, during each function call, this table is quickly searched to check if the called function has an equivalent alternative in the host-side. If not found, the gyhcallback callback is used to call back the object-side function.

[0141] Furthermore, the method for accelerators to simulate execution across instruction set architectures also includes a fifth optimization step:

[0142] During the linking phase, instead of generating a separate unified host library, each host code module is directly embedded into its corresponding object linking result file.

[0143] When a cross-architecture call occurs, the host side uses the entry address of the object function for offset addressing, directly locates and executes the embedded host-side equivalent function code.

[0144] Optimization 5: Object programs with embedded host code, details of which are as follows:

[0145] Figure 5 In step ③, the various gyhlib modules are merged together to form a complete gyhlib. The purpose of this is to assign uniform and consecutive numbers to all functions, thereby allowing the host to quickly address and execute equivalent functions when a gyhcall occurs. However, this method has a serious problem: when the number of libraries involved in the entire object application software stack is extremely large, it will cause gyhlib to become too large, occupying unnecessary additional memory address space during runtime.

[0146] This problem can be solved by directly embedding the host code into the object program. For example... Figure 9 The diagram shown illustrates the method, including steps ①, ②, and... Figure 5 The process is the same, but in step ③, this invention directly embeds the obtained gyhlib module into its corresponding linker file. To eliminate the need for uniform numbering of all functions, this invention directly fills the code of the host-side equivalent function into the original position of the object function in the linker file. Thus, when gyhcall occurs, the host side only needs to offset a few bytes from the object function's entry address to find the equivalent host function. This method requires modification to both the compiler and linker.

[0147] Experimental example:

[0148] This experimental example uses matrix exponentiation as an application scenario. This invention is used to calculate the sum of all elements of a given order matrix raised to a specified power. Its core lies in improving cross-architecture simulation execution efficiency through a scheduling mechanism implemented via function separation, callback stub injection, and host-side equivalence. The formula to be calculated is as follows:

[0149]

[0150] Implementation environment and equipment parameters:

[0151] Hardware platform: x86_64 architecture server (CPU model: Intel Core i7-12700K, memory 32GB DDR5 4800MHz);

[0152] Operating system: Ubuntu 22.04 LTS 64-bit;

[0153] Software tools: QEMU 9.1.50 (cross-architecture simulator, supports aarch64→x86_64 instruction translation), LLVM18.1 (intermediate code generation and processing tool);

[0154] Experimental test procedure content:

[0155] The core content of this experimental example program includes matrix initialization, release, assignment, multiplication, exponentiation, element summation, and callback scheduling auxiliary functions. The functional definitions and implementation logic of each function are as follows:

[0156] The matrix initialization function (Mat_init) receives a matrix pointer and an order parameter, allocates memory space for rank×rank double-type elements of the matrix, and initializes the rank member variable; if memory allocation fails, it will trigger an abnormal termination.

[0157] The matrix release function (Mat_free) receives a matrix pointer and releases the memory space pointed to by the data member variable.

[0158] The function to get the matrix order (Mat_rank) takes a matrix pointer and returns the value of the matrix's rank member variable.

[0159] The matrix data pointer acquisition function (Mat_data) receives a matrix pointer and returns a pointer to the data member variable.

[0160] The matrix element assignment function (Mat_set) takes a matrix pointer and a target value v, assigns the value v to all elements of the matrix, and returns a matrix pointer.

[0161] The matrix multiplication function (Mat_mul) takes two pointers to input matrices (which must be of the same order), creates a result matrix, calculates the product of the two matrices using a triple loop (according to the matrix multiplication rules, the element in the i-th row and j-th column of the result matrix is ​​the sum of the products of the corresponding elements in the i-th row of the first matrix and the j-th column of the second matrix), and returns the result matrix.

[0162] The matrix exponentiation function (Mat_pow) takes a matrix pointer and the exponent n, initializes the identity matrix as an intermediate result, calculates the nth power of the input matrix through n matrix multiplications, and returns the exponentiation result matrix (the intermediate result matrix needs to be dynamically released to avoid memory leaks).

[0163] The matrix element summation function (Mat_sum) takes a matrix pointer, iterates through all elements and sums them up, and returns the sum.

[0164] Implementation steps:

[0165] The matrix power sum calculation and cross-architecture optimization execution flow for this experimental example are as follows:

[0166] Separation of program preprocessing and functions:

[0167] The matrix power calculation program implemented in C language is compiled and intermediate code is generated to obtain the LLVMIR intermediate representation.

[0168] Identify the core functions in the program (Mat_init, Mat_mul, Mat_pow, etc.), separate them from the original program, and inject the corresponding callback stub functions (__gyh_call_back_XXX) into the original program to form stub code.

[0169] The separated core functions are compiled into equivalent implementations on the host side (x86_64 architecture), and linked with callback scheduling logic (gyh_call, __gyh_call_back__, etc.) to form a host-side execution module.

[0170] Cross-architecture emulation execution configuration:

[0171] The callback scheduling mechanism of this invention is integrated into the QEMU simulator, and a cross-architecture execution environment of aarch64→x86_64 is configured.

[0172] The stub code is compiled into a target program with an aarch64 architecture, and the host-side execution module is loaded as an extension module of the QEMU simulator.

[0173] Matrix exponentiation calculation execution:

[0174] Input parameters: matrix order rank=100, power n=100;

[0175] Initialize the matrix: Call Mat_init to create a 100th order matrix, and use Mat_set to assign the value 1 / 100 to all elements;

[0176] Exponentiation: Call Mat_pow to calculate the matrix to the power of 100;

[0177] Element-wise summation: Call Mat_sum to calculate the sum of all elements in the matrix resulting from the exponentiation operation;

[0178] Output: Prints the matrix order, power, and summation result, and releases all dynamically allocated memory.

[0179] Performance data collection:

[0180] Execute the following three types of programs on the x86_64 platform and record the total execution time:

[0181] A native x86_64 compiled matrix exponentiation program;

[0182] Programs compiled using the aarch64 architecture (executed via QEMU's default translation mechanism);

[0183] The aarch64 program is optimized based on the technology of this invention (execution is achieved by calling the native host side through callback scheduling).

[0184] Experimental data:

[0185] List of execution time test results for three types of programs

[0186] Execution method Matrix order Power Summation result Total execution time (s) x86_64 native execution 100 100 100.0 0.06 QEMU defaults to emulating aarch64 execution. 100 100 100.0 1.01 This invention optimizes simulation execution 100 100 100.0 0.35

[0187] Note: The summation result is always 100.0. Since all elements of the initial matrix are 1 / 100, the sum of all elements of its 100th power matrix is ​​still 100.0, which verifies the correctness of the calculation result.

[0188] Analysis of experimental results:

[0189] Correctness verification: The summation results of the three execution methods are consistent, all being 100.0, indicating that the function separation, callback scheduling, and host-side equivalent implementation of the present invention have not changed the functional logic of the original program, thus ensuring the accuracy of the calculation results.

[0190] Performance optimization results: Compared with QEMU's default cross-architecture translation execution (1.01s), the technology of this invention reduces the execution time to 0.35s, and the performance is improved by 2.89 times; verifying the performance advantage of this invention in cross-architecture simulation scenarios.

[0191] The core reason for the performance improvement is that by separating functions and implementing scheduling natively on the host side, the overhead of QEMU instruction translation is avoided, and the hardware performance of the host architecture is fully utilized.

[0192] It should be understood that, in existing technologies, there have been preliminary explorations of methods to hijack third-party library function calls and forward them to native implementations on different underlying instruction set architectures (ISAs). For example, the box64 tool can hijack calls from x86 programs to specific functions in libraries such as libc, libm, SDL, and OpenGL, and forward them to native versions of these libraries on other ISAs such as ARM and RISC-V for execution. However, such existing methods generally have significant limitations: firstly, their forwarding logic generally relies on manual coding, resulting in high development and maintenance costs, and making it difficult to cover a large number of functions; secondly, their application scope is usually limited to a few common underlying libraries, and cannot be universally applied to any program or custom library. Compared to existing technologies, the core innovation of this invention lies in the first-time deep integration of the fundamental principle of "function call forwarding" with modern program compilation and building technologies. Through automated processing flows integrated into the compilation chain (such as function separation, stub and host code generation, call conversion, etc.), this invention achieves universal, automated identification and accelerated replacement of a large number of function calls in high-level language programs, thereby constructing a systematic, manual-intervention-free cross-ISA program accelerated execution framework.

[0193] The above is a detailed description of the preferred embodiments of the present invention. However, the present invention is not limited to the embodiments described. Those skilled in the art can make various equivalent modifications or substitutions without departing from the spirit of the present invention. All such equivalent modifications or substitutions are included within the scope defined by the claims of this application.

Claims

1. A method for accelerating the simulated execution of programs across instruction set architectures, characterized in that, Includes the following steps: S1: During the compilation phase, for programs written in high-level languages ​​and running on the object side, functions that meet predetermined conditions in each translation unit are separated to generate independent host-side intermediate code files, and the intermediate code files are compiled into host-side object files; at the same time, stub functions with the same signature as the functions are generated in the original translation unit. S2: During the linking phase, based on the linking process of the original program and the target file on the host side, host code modules corresponding one-to-one with the original linking result files are generated, and module-level data is generated for each host code module. S3: Aggregate all host code modules to form a unified host program library, and assign unique consecutive integer identifiers to all object functions in the host program library; S4: Based on the host program library, generate a stub module that corresponds one-to-one with the object linking result and works on the object side. The stub module is used to complete the missing function identifiers in the object linking result. S5: During program execution, the stub functions, stub modules, and host program libraries are used to forward object-side function calls to equivalent host-side functions for execution through call conversion, interpretation reentrancy, and data layout adaptation mechanisms. After execution is completed, the program returns to the object side to continue execution. The call conversion includes the following steps: Parameter conversion: Retrieve parameters from the simulator's virtual registers and the object call stack according to the object application's binary interface, and then rearrange them into the host-side registers and call stack according to the host application's binary interface; Call triggering: Switching control flow from the object side to the host side through predefined cross-architecture call instructions or system calls; Return value conversion: Retrieve the return value data from the host side's registers and call stack according to the host application's binary interface, and then rearrange it into the simulator's data structure and the object's call stack according to the object application's binary interface; The interpretation reentrancy includes the following steps: Before the object-side stub function triggers a cross-architecture call, a memory area is reserved on the object call stack to accommodate the host-side equivalent function stack frame and the host-side execution context; When a cross-architecture call is triggered, the simulator saves the address of the next instruction of the object program to the object call stack, creates a stack frame for the host-side equivalent function in the reserved memory area, and switches the control flow to the execution of the host-side equivalent function; When the host-side equivalent function needs to call back the object-side function, the callback mechanism is triggered to enter the callback stub function on the object side; The callback stub function retrieves parameters from the host-side stack frame, calls the specified object-side function, collects the return value to the host-side stack frame after the object-side function has finished executing, and then switches back to the host side to continue execution.

2. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 1, characterized in that, The call conversion step also includes: In the stub function, collect pointers or addresses of all external symbols involved in the delimited function body and store them in a parameter structure; When the call is triggered, the parameter structure is passed to the host-side equivalent function; The host-side equivalent function accesses data in the object's address space through pointers or addresses in the parameter structure.

3. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 1, characterized in that, The data layout adaptation includes the following steps: When separating object functions into host-side intermediate code, traverse and identify instructions that are affected by the differences in binary interface data layout between the object and the host application; Replace the affected instructions with calls to predefined, architecture-independent primitive functions; The primitive functions are marked as inline functions to eliminate calling overhead and allow compiler optimization.

4. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 1, characterized in that, It also includes the first optimization step: When the object function body contains code that cannot be directly compiled on the host side, the code portion bound to the object architecture will be externalized into an independent object-side function; In the host-side equivalent function, the external object-side function is called through a callback mechanism.

5. The method for accelerating cross-instruction set architecture simulation execution of programs according to any one of claims 1-4, characterized in that, It also includes a second optimization step: When the program is loaded or the dynamic library is initialized, a global reference table is constructed for each host code module. The global reference table contains the addresses of all external symbols involved in the functions of the module. When the conversion is invoked, the pointer to the global reference table is directly passed to the host-side equivalent function to avoid dynamic construction on each call.

6. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 5, characterized in that, It also includes a third optimization step: When two object functions that have been separated to the host side need to call each other, the function call is made directly on the host side without going through the callback mechanism of switching between host and object; Before triggering cross-architecture calls, the object-side stub function needs to reserve a sufficiently large stack space on the object call stack to accommodate possible multi-level nested calls on the host side.

7. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 5, characterized in that, It also includes a fourth optimization step: When the program starts or the dynamic library is loaded, a dynamic callback forwarding table is constructed. The dynamic callback forwarding table records the mapping of all object-side function addresses to their corresponding host-side equivalent function addresses. Each time a function call occurs, the dynamic callback forwarding table is first queried. If an equivalent function on the host side is found, it is called directly; otherwise, the object side function is called through the callback mechanism.

8. The method for accelerating cross-instruction set architecture simulation execution of programs according to claim 1, characterized in that, It also includes a fifth optimization step: During the linking phase, instead of generating a separate unified host library, each host code module is directly embedded into its corresponding object linking result file. When a cross-architecture call occurs, the host side uses the entry address of the object function for offset addressing, directly locates and executes the embedded host-side equivalent function code.

Citation Information

Patent Citations

  • Binary translation method and device, electronic equipment and readable storage medium

    CN118484237A

  • Unified programming model compiling and runtime system oriented to Shenwei supercomputing platform

    CN120631368A