mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-11 02:19:30 +00:00
Merge pull request #6900 from MauriceElliott/maurice/playdate_support
Playdate Support
This commit is contained in:
@@ -171,6 +171,7 @@ enum Subtarget : u32 {
|
||||
Subtarget_iPhone,
|
||||
Subtarget_iPhoneSimulator,
|
||||
Subtarget_Android,
|
||||
Subtarget_Playdate,
|
||||
|
||||
Subtarget_COUNT,
|
||||
Subtarget_Invalid, // NOTE(harold): Must appear after _COUNT as this is not a real subtarget
|
||||
@@ -181,6 +182,7 @@ gb_global String subtarget_strings[Subtarget_COUNT] = {
|
||||
str_lit("iphone"),
|
||||
str_lit("iphonesimulator"),
|
||||
str_lit("android"),
|
||||
str_lit("playdate"),
|
||||
};
|
||||
|
||||
|
||||
@@ -1957,6 +1959,16 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
bc->no_plt = LLVM_VERSION_MAJOR >= 19;
|
||||
break;
|
||||
}
|
||||
} else if (subtarget == Subtarget_Playdate) {
|
||||
// Playdate uses the cortex-m7 as well and an FPU, requiring thumb instructions and hard floats.
|
||||
bc->microarch = str_lit("cortex-m7");
|
||||
bc->metrics.target_triplet = str_lit("thumbv7em-none-eabihf");
|
||||
// Remove MOVW/MOVT instructions as playdate only handles R_ARM_ABS32 relocations.
|
||||
if(bc->target_features_string.len > 0) {
|
||||
bc->target_features_string = concatenate_strings(permanent_allocator(), bc->target_features_string, str_lit(",no-movt"));
|
||||
} else {
|
||||
bc->target_features_string = str_lit("no-movt");
|
||||
}
|
||||
}
|
||||
|
||||
if (metrics->os == TargetOs_windows ||
|
||||
|
||||
@@ -1247,6 +1247,7 @@ gb_internal void init_universal(void) {
|
||||
{"iPhone", Subtarget_iPhone},
|
||||
{"iPhoneSimulator", Subtarget_iPhoneSimulator},
|
||||
{"Android", Subtarget_Android},
|
||||
{"Playdate", Subtarget_Playdate},
|
||||
};
|
||||
|
||||
auto fields = add_global_enum_type(str_lit("Odin_Platform_Subtarget_Type"), values, gb_count_of(values));
|
||||
|
||||
@@ -186,9 +186,11 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
|
||||
|
||||
lbCallingConventionKind cc_kind = lbCallingConvention_C;
|
||||
// TODO(bill): Clean up this logic
|
||||
if (!is_arch_wasm()) {
|
||||
if (selected_subtarget == Subtarget_Playdate) {
|
||||
cc_kind = lbCallingConvention_ARM_AAPCS_VFP;
|
||||
} else if (!is_arch_wasm()) {
|
||||
cc_kind = lb_calling_convention_map[calling_convention];
|
||||
}
|
||||
}
|
||||
// if (build_context.metrics.arch == TargetArch_amd64) {
|
||||
// if (build_context.metrics.os == TargetOs_windows) {
|
||||
// if (cc_kind == lbCallingConvention_C) {
|
||||
@@ -1554,14 +1556,14 @@ namespace lbAbiWasm {
|
||||
|
||||
namespace lbAbiArm32 {
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined, ProcCallingConvention calling_convention);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = permanent_alloc_item<lbFunctionType>();
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
|
||||
ft->ret = compute_return_type(c, return_type, return_is_defined);
|
||||
ft->ret = compute_return_type(c, return_type, return_is_defined, calling_convention);
|
||||
ft->calling_convention = calling_convention;
|
||||
return ft;
|
||||
}
|
||||
@@ -1604,7 +1606,10 @@ namespace lbAbiArm32 {
|
||||
} else {
|
||||
i64 sz = lb_sizeof(t);
|
||||
i64 a = lb_alignof(t);
|
||||
if (is_calling_convention_odin(calling_convention) && sz > 8) {
|
||||
// Added to support hard floats included in the playdates cortex-m7.
|
||||
if (calling_convention == ProcCC_CDecl && selected_subtarget == Subtarget_Playdate) {
|
||||
args[i] = lb_arg_type_direct(t);
|
||||
} else if (is_calling_convention_odin(calling_convention) && sz > 8) {
|
||||
// Minor change to improve performance using the Odin calling conventions
|
||||
args[i] = lb_arg_type_indirect(t, nullptr);
|
||||
} else if (a <= 4) {
|
||||
@@ -1619,10 +1624,13 @@ namespace lbAbiArm32 {
|
||||
return args;
|
||||
}
|
||||
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) {
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined, ProcCallingConvention calling_convention) {
|
||||
if (!return_is_defined) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
} else if (!is_register(return_type, true)) {
|
||||
if (calling_convention == ProcCC_CDecl && selected_subtarget == Subtarget_Playdate) {
|
||||
return lb_arg_type_direct(return_type);
|
||||
}
|
||||
switch (lb_sizeof(return_type)) {
|
||||
case 1: return lb_arg_type_direct(LLVMIntTypeInContext(c, 8), return_type, nullptr, nullptr);
|
||||
case 2: return lb_arg_type_direct(LLVMIntTypeInContext(c, 16), return_type, nullptr, nullptr);
|
||||
|
||||
@@ -452,7 +452,9 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name
|
||||
|
||||
Type *pt = p->type;
|
||||
lbCallingConventionKind cc_kind = lbCallingConvention_C;
|
||||
if (!is_arch_wasm()) {
|
||||
if (selected_subtarget == Subtarget_Playdate) {
|
||||
cc_kind = lbCallingConvention_ARM_AAPCS_VFP;
|
||||
} else if (!is_arch_wasm()) {
|
||||
cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
|
||||
}
|
||||
LLVMSetFunctionCallConv(p->value, cc_kind);
|
||||
@@ -994,6 +996,9 @@ gb_internal lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue
|
||||
LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
|
||||
|
||||
auto llvm_cc = lb_calling_convention_map[proc_type->Proc.calling_convention];
|
||||
if (selected_subtarget == Subtarget_Playdate) {
|
||||
llvm_cc = lbCallingConvention_ARM_AAPCS_VFP;
|
||||
}
|
||||
LLVMSetInstructionCallConv(ret, llvm_cc);
|
||||
|
||||
LLVMAttributeIndex param_offset = LLVMAttributeIndex_FirstArgIndex;
|
||||
|
||||
@@ -1199,8 +1199,10 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
bool found = false;
|
||||
|
||||
if (selected_target_metrics->metrics->os != TargetOs_darwin &&
|
||||
selected_target_metrics->metrics->os != TargetOs_linux ) {
|
||||
gb_printf_err("-subtarget can only be used with darwin and linux based targets at the moment\n");
|
||||
selected_target_metrics->metrics->os != TargetOs_linux &&
|
||||
(selected_target_metrics->metrics->os != TargetOs_freestanding ||
|
||||
selected_target_metrics->metrics->arch != TargetArch_arm32)) {
|
||||
gb_printf_err("-subtarget can only be used with darwin, linux or freestanding_arm32 based targets at the moment\n");
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
@@ -3202,7 +3204,7 @@ gb_internal int print_show_help(String const arg0, String command, String option
|
||||
|
||||
if (build) {
|
||||
if (print_flag("-subtarget:<subtarget>")) {
|
||||
print_usage_line(2, "[Darwin and Linux only]");
|
||||
print_usage_line(2, "[Darwin, Linux and Freestanding ARM32 only]");
|
||||
print_usage_line(2, "Available subtargets:");
|
||||
String prefix = str_lit("-subtarget:");
|
||||
for (u32 i = 1; i < Subtarget_COUNT; i++) {
|
||||
|
||||
Reference in New Issue
Block a user