The frontend converts CIL opcodes to intermediate representation opcodes which are listed
here via the function
EncodeOpcode (and the helper functions in that file). The code then undergoes a series of optimization passes before being converted to machine code by the code snippets referenced in the various backends. These are listed in the arch_init_opcodes() function (e.g. for
x86_64/i586 and for
ARM).
Air wrote:
why did names for assembly functions look like this:
Code:
_ZN8libsupcs17libsupcs#2Ex86_643CpuM_0_7get_Cr2_Ry_P0:
This is a mangled version of the C# function:
Code:
namespace libsupcs.x86_64 {
class Cpu {
public extern static ulong Cr2 { get; }
}
}
in module libsupcs. The getter function of the Cr2 property is tagged as [MethodImpl(MethodImplOptions.InternalCall)] to identify to the compiler that it doesn't have an implementation and that the compiler will provide it instead. When a function like this is called, first
enc_intcall() is called to see if the compiler actually does provide it. If it does, then the function is inlined, else a call to an external function with that mangled name is emitted. Eventually I plan on incorporating a lot of these cpu-specific functions as inlineable internal calls, I just haven't got around to it yet.
The reason the names are mangled is that, exactly like C++, multiple functions in both the same and different classes can have the same name, and therefore each needs a unique identifier to use in the linking phase. The mangling rules are
here.
Regards,
John.