Add intrinsics.syscall_bsd

This is a BSD-style syscall that checks for a high Carry Flag as the
error state. If the CF is high, the boolean return value is false, and
if it is low (no errors) then the boolean return value is true.
This commit is contained in:
Feoramund
2024-06-12 13:07:13 -04:00
parent 35a845b93f
commit 5b5402fb23
5 changed files with 195 additions and 54 deletions
+52 -6
View File
@@ -5089,15 +5089,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
isize max_arg_count = 32;
switch (build_context.metrics.os) {
case TargetOs_windows:
case TargetOs_freestanding:
error(call, "'%.*s' is not supported on this platform (%.*s)", LIT(builtin_name), LIT(target_os_names[build_context.metrics.os]));
break;
case TargetOs_darwin:
case TargetOs_linux:
case TargetOs_essence:
case TargetOs_freebsd:
case TargetOs_openbsd:
case TargetOs_haiku:
switch (build_context.metrics.arch) {
case TargetArch_i386:
@@ -5107,6 +5101,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
break;
}
break;
default:
error(call, "'%.*s' is not supported on this platform (%.*s)", LIT(builtin_name), LIT(target_os_names[build_context.metrics.os]));
break;
}
if (ce->args.count > max_arg_count) {
@@ -5120,6 +5117,55 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return true;
}
break;
case BuiltinProc_syscall_bsd:
{
convert_to_typed(c, operand, t_uintptr);
if (!is_type_uintptr(operand->type)) {
gbString t = type_to_string(operand->type);
error(operand->expr, "Argument 0 must be of type 'uintptr', got %s", t);
gb_string_free(t);
}
for (isize i = 1; i < ce->args.count; i++) {
Operand x = {};
check_expr(c, &x, ce->args[i]);
if (x.mode != Addressing_Invalid) {
convert_to_typed(c, &x, t_uintptr);
}
convert_to_typed(c, &x, t_uintptr);
if (!is_type_uintptr(x.type)) {
gbString t = type_to_string(x.type);
error(x.expr, "Argument %td must be of type 'uintptr', got %s", i, t);
gb_string_free(t);
}
}
isize max_arg_count = 32;
switch (build_context.metrics.os) {
case TargetOs_freebsd:
case TargetOs_netbsd:
case TargetOs_openbsd:
switch (build_context.metrics.arch) {
case TargetArch_amd64:
case TargetArch_arm64:
max_arg_count = 7;
break;
}
break;
default:
error(call, "'%.*s' is not supported on this platform (%.*s)", LIT(builtin_name), LIT(target_os_names[build_context.metrics.os]));
break;
}
if (ce->args.count > max_arg_count) {
error(ast_end_token(call), "'%.*s' has a maximum of %td arguments on this platform (%.*s), got %td", LIT(builtin_name), max_arg_count, LIT(target_os_names[build_context.metrics.os]), ce->args.count);
}
operand->mode = Addressing_Value;
operand->type = make_optional_ok_type(t_uintptr);
return true;
}
break;
case BuiltinProc_type_base_type: