mirror of
https://github.com/open-goal/jak-project
synced 2026-09-07 11:36:26 -04:00
de25f39439
Got OpenGOAL building and running natively on Apple Silicon. This is the rest of the port after the smaller arm64 emitter PRs. I was told pushing one big PR was okay. This covers goalc, the runtime, linker, kernel and the GOAL asm. The new paths have native tests. I also found four more emitter bugs while running it. They're in scalar sqrt, 128-bit stores, scalar max and indexed stores above 4 GB. Spent a while cleaning it up so it's easier to read. 4am gotta sleep lol Closes #3841 --------- Co-authored-by: Tyler Wilding <xtvaser@gmail.com>
60 lines
2.2 KiB
C++
60 lines
2.2 KiB
C++
#include "CallingConvention.h"
|
|
|
|
#include "common/util/Assert.h"
|
|
|
|
CallingConvention get_function_calling_convention(const TypeSpec& function_type,
|
|
const TypeSystem& type_system,
|
|
emitter::InstructionSet instr_set) {
|
|
ASSERT(function_type.base_type() == "function");
|
|
ASSERT(function_type.arg_count() > 0);
|
|
ASSERT(function_type.arg_count() <= 9);
|
|
|
|
int gpr_idx = 0;
|
|
|
|
CallingConvention cc;
|
|
|
|
if (function_type.arg_count() == 2 && function_type.get_arg(0).print() == "_varargs_") {
|
|
for (int i = 0; i < 8; i++) {
|
|
cc.arg_regs.push_back(emitter::reg_info(instr_set).get_gpr_arg_reg(gpr_idx++));
|
|
}
|
|
} else {
|
|
int simd_idx = 0;
|
|
for (int i = 0; i < (int)function_type.arg_count() - 1; i++) {
|
|
auto info = type_system.lookup_type_allow_partial_def(function_type.get_arg(i));
|
|
auto load_size = type_system.get_load_size_allow_partial_def(function_type.get_arg(i));
|
|
if (dynamic_cast<const ValueType*>(info) && load_size == 16) {
|
|
cc.arg_regs.push_back(emitter::reg_info(instr_set).get_simd_arg_reg(simd_idx++));
|
|
} else {
|
|
cc.arg_regs.push_back(emitter::reg_info(instr_set).get_gpr_arg_reg(gpr_idx++));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (function_type.last_arg() != TypeSpec("none")) {
|
|
if (type_system.get_load_size_allow_partial_def(function_type.last_arg()) == 16) {
|
|
cc.return_reg = emitter::reg_info(instr_set).get_simd_ret_reg();
|
|
} else {
|
|
cc.return_reg = emitter::reg_info(instr_set).get_gpr_ret_reg();
|
|
}
|
|
}
|
|
|
|
return cc;
|
|
}
|
|
|
|
std::vector<emitter::Register> get_arg_registers(const TypeSystem& type_system,
|
|
const std::vector<TypeSpec>& arg_types,
|
|
emitter::InstructionSet instr_set) {
|
|
std::vector<emitter::Register> result;
|
|
int gpr_idx = 0;
|
|
int simd_idx = 0;
|
|
for (auto& type : arg_types) {
|
|
auto load_size = type_system.get_load_size_allow_partial_def(type);
|
|
if (load_size == 16) {
|
|
result.push_back(emitter::reg_info(instr_set).get_simd_arg_reg(simd_idx++));
|
|
} else {
|
|
result.push_back(emitter::reg_info(instr_set).get_gpr_arg_reg(gpr_idx++));
|
|
}
|
|
}
|
|
return result;
|
|
}
|