@ -1,3 +1,6 @@
#!/usr/bin/python3
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
@ -378,7 +381,7 @@ def emit_gather(sources, name, type_name, reg_size):
if len ( sources ) == 1 :
s , = sources
line = f " {name} = Convert<{type_name}>({get_fn}(args, {s})); "
line = f " {type_name} { name} = Convert<{type_name}>({get_fn}(args, {s})); "
return [ line ]
var_type = f " std::array<uint{reg_size*8}_t, {len(sources)}> "
@ -386,10 +389,9 @@ def emit_gather(sources, name, type_name, reg_size):
f " {var_type} {name}_gather{{}}; "
]
for i in range ( 0 , len ( sources ) ) :
lines . append (
f " {name}_gather[{i}] = {get_fn}(args, {sources[i]}); " )
lines . append ( f " {name}_gather[{i}] = {get_fn}(args, {sources[i]}); " )
lines . append ( f " {name} = Convert<{type_name}>({name}_gather); " )
lines . append ( f " {type_name} { name} = Convert<{type_name}>({name}_gather); " )
return lines
@ -405,14 +407,9 @@ def emit_scatter(destinations, name, reg_size):
return [ line ]
var_type = f " std::array<{reg_type}, {len(destinations)}> "
lines = [
f " auto {name}_scatter = Convert<{var_type}>({name}); "
]
lines = [ f " auto {name}_scatter = Convert<{var_type}>({name}); " ]
for i in range ( 0 , len ( destinations ) ) :
lines . append (
f " {set_fn}(args, {destinations[i]}, {name}_scatter[{i}]); " )
lines . append ( f " {set_fn}(args, {destinations[i]}, {name}_scatter[{i}]); " )
return lines
@ -436,25 +433,8 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size):
f " static void SvcWrap_{wrapped_fn}{suffix}(Core::System& system, std::span<uint64_t, 8> args) {{ "
]
# Get everything ready.
for return_type , _ in return_write :
lines . append ( f " {return_type} ret{{}}; " )
if return_write :
lines . append ( " " )
for output_type , var_name , _ , is_address in output_writes :
output_type = " uint64_t " if is_address else output_type
lines . append ( f " {output_type} {var_name}{{}}; " )
for input_type , var_name , _ in input_reads :
lines . append ( f " {input_type} {var_name}{{}}; " )
if output_writes or input_reads :
lines . append ( " " )
for input_type , var_name , sources in input_reads :
lines + = emit_gather ( sources , var_name , input_type , byte_size )
if input_reads :
lines . append ( " " )
# Build the call.
call_arguments = [ " system " ]
@ -464,16 +444,18 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size):
else :
call_arguments . append ( arg . var_name )
# Get everything ready.
for output_type , var_name , _ , is_address in output_writes :
output_type = " uint64_t " if is_address else output_type
lines . append ( f " {output_type} {var_name}{{}}; " )
line = " "
if return_write :
line + = " ret = "
for return_type , _ in return_write :
line + = f " {return_type} ret = "
line + = f " {wrapped_fn}{suffix}({ ' , ' .join(call_arguments)}); "
lines . append ( line )
if return_write or output_writes :
lines . append ( " " )
# Write back the return value and outputs.
for _ , destinations in return_write :
lines + = emit_scatter ( destinations , " ret " , byte_size )
@ -485,10 +467,13 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size):
COPYRIGHT = """ \
/ / SPDX - FileCopyrightText : Copyright 2025 Eden Emulator Project
/ / SPDX - License - Identifier : GPL - 3.0 - or - later
/ / SPDX - FileCopyrightText : Copyright 2023 yuzu Emulator Project
/ / SPDX - License - Identifier : GPL - 2.0 - or - later
/ / SPDX - License - Identifier : GPL - 2.0 - or - late
/ / This file is automatically generated using svc_generator . py .
/ / DO NOT MODIFY IT MANUALLY
"""
PROLOGUE_H = """
@ -505,13 +490,9 @@ class System;
#include "core/hle/result.h"
namespace Kernel : : Svc {
/ / clang - format off
"""
EPILOGUE_H = """
/ / clang - format on
/ / Custom ABI .
Result ReplyAndReceiveLight ( Core : : System & system , Handle handle , uint32_t * args ) ;
Result ReplyAndReceiveLight64From32 ( Core : : System & system , Handle handle , uint32_t * args ) ;
@ -553,7 +534,7 @@ PROLOGUE_CPP = """
namespace Kernel : : Svc {
static uint32_t GetArg32 ( std : : span < uint64_t , 8 > args , int n ) {
return static_cast < uint32_t > ( args [ n ] ) ;
return uint32_t ( args [ n ] ) ;
}
static void SetArg32 ( std : : span < uint64_t , 8 > args , int n , uint32_t result ) {
@ -574,37 +555,27 @@ template <typename To, typename From>
requires ( std : : is_trivial_v < To > & & std : : is_trivially_copyable_v < From > )
static To Convert ( const From & from ) {
To to { } ;
if constexpr ( sizeof ( To ) > = sizeof ( From ) ) {
if constexpr ( sizeof ( To ) > = sizeof ( From ) )
std : : memcpy ( std : : addressof ( to ) , std : : addressof ( from ) , sizeof ( From ) ) ;
} else {
else
std : : memcpy ( std : : addressof ( to ) , std : : addressof ( from ) , sizeof ( To ) ) ;
}
return to ;
}
/ / clang - format off
"""
EPILOGUE_CPP = """
/ / clang - format on
void Call ( Core : : System & system , u32 imm ) {
auto & kernel = system . Kernel ( ) ;
auto & process = GetCurrentProcess ( kernel ) ;
std : : array < uint64_t , 8 > args ;
kernel . CurrentPhysicalCore ( ) . SaveSvcArguments ( process , args ) ;
kernel . EnterSVCProfile ( ) ;
if ( process . Is64Bit ( ) ) {
/ / kernel . EnterSVCProfile ( ) ;
if ( process . Is64Bit ( ) )
Call64 ( system , imm , args ) ;
} else {
else
Call32 ( system , imm , args ) ;
}
kernel . ExitSVCProfile ( ) ;
/ / kernel . ExitSVCProfile ( ) ;
kernel . CurrentPhysicalCore ( ) . LoadSvcArguments ( process , args ) ;
}
@ -617,12 +588,11 @@ def emit_call(bitness, names, suffix):
indent = " "
lines = [
f " static void Call{bit_size}(Core::System& system, u32 imm, std::span<uint64_t, 8> args) {{ " ,
f " {indent}switch (static_cast< SvcId> (imm)) {{ "
f " {indent}switch (SvcId(imm)) {{ "
]
for _ , name in names :
lines . append ( f " {indent}case SvcId::{name}: " )
lines . append ( f " {indent*2}return SvcWrap_{name}{suffix}(system, args); " )
lines . append ( f " {indent}case SvcId::{name}: return SvcWrap_{name}{suffix}(system, args); " )
lines . append ( f " {indent}default: " )
lines . append (
@ -692,7 +662,7 @@ def main():
call_64 = emit_call ( BIT_64 , names , SUFFIX_NAMES [ BIT_64 ] )
enum_decls = build_enum_declarations ( )
with open ( " svc.h " , " w " ) as f :
with open ( " src/core/hle/kernel/s vc.h " , " w " ) as f :
f . write ( COPYRIGHT )
f . write ( PROLOGUE_H )
f . write ( " \n " . join ( svc_fw_declarations ) )
@ -704,7 +674,7 @@ def main():
f . write ( enum_decls )
f . write ( EPILOGUE_H )
with open ( " svc.cpp " , " w " ) as f :
with open ( " src/core/hle/kernel/s vc.cpp " , " w " ) as f :
f . write ( COPYRIGHT )
f . write ( PROLOGUE_CPP )
f . write ( emit_size_check ( ) )