aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-10-30 22:05:29 +0000
committergingerBill <bill@gingerbill.org>2022-10-30 22:05:29 +0000
commit6a14c3edb42fbbcc9ab0df962458f1da16f6f508 (patch)
tree1ff3d2f93a65e65aaa12a304c4bf09764a50163d /src
parent2cd895c50b788c6bec8a198820611c6a31ee31a7 (diff)
Make `raw_data` an intrinsic rather a `@(builtin)` runtime procedure
Diffstat (limited to 'src')
-rw-r--r--src/check_builtin.cpp53
-rw-r--r--src/checker_builtin_procs.hpp4
-rw-r--r--src/llvm_backend_proc.cpp31
3 files changed, 88 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index fc889fb28..b8bf1bcc7 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -3651,6 +3651,59 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
operand->mode = Addressing_NoValue;
break;
+ case BuiltinProc_raw_data:
+ {
+ Operand x = {};
+ check_expr(c, &x, ce->args[0]);
+ if (x.mode == Addressing_Invalid) {
+ return false;
+ }
+ if (!is_operand_value(x)) {
+ gbString s = expr_to_string(x.expr);
+ error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
+ gb_string_free(s);
+ return false;
+ }
+ Type *t = base_type(x.type);
+
+ operand->mode = Addressing_Value;
+ operand->type = nullptr;
+ switch (t->kind) {
+ case Type_Slice:
+ operand->type = alloc_type_multi_pointer(t->MultiPointer.elem);
+ break;
+ case Type_DynamicArray:
+ operand->type = alloc_type_multi_pointer(t->DynamicArray.elem);
+ break;
+ case Type_Basic:
+ if (t->Basic.kind == Basic_string) {
+ operand->type = alloc_type_multi_pointer(t_u8);
+ }
+ break;
+ case Type_Pointer:
+ case Type_MultiPointer:
+ {
+ Type *base = base_type(type_deref(t, true));
+ switch (base->kind) {
+ case Type_Array:
+ case Type_EnumeratedArray:
+ case Type_SimdVector:
+ operand->type = alloc_type_multi_pointer(base_array_type(base));
+ break;
+ }
+ }
+ break;
+ }
+
+ if (operand->type == nullptr) {
+ gbString s = type_to_string(x.type);
+ error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
+ gb_string_free(s);
+ return false;
+ }
+ }
+ break;
+
case BuiltinProc_read_cycle_counter:
operand->mode = Addressing_Value;
operand->type = t_i64;
diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp
index b8cd84cc6..c59ae7867 100644
--- a/src/checker_builtin_procs.hpp
+++ b/src/checker_builtin_procs.hpp
@@ -42,6 +42,8 @@ enum BuiltinProcId {
BuiltinProc_unreachable,
+ BuiltinProc_raw_data,
+
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
// "Intrinsics"
@@ -338,6 +340,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("unreachable"), 0, false, Expr_Expr, BuiltinProcPkg_builtin, /*diverging*/true},
+ {STR_LIT("raw_data"), 1, false, Expr_Expr, BuiltinProcPkg_builtin},
+
{STR_LIT(""), 0, true, Expr_Expr, BuiltinProcPkg_builtin}, // DIRECTIVE
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 4d7896c8a..a88c8f2ee 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -1850,6 +1850,37 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
lb_emit_unreachable(p);
return {};
+ case BuiltinProc_raw_data:
+ {
+ lbValue x = lb_build_expr(p, ce->args[0]);
+ Type *t = base_type(x.type);
+ lbValue res = {};
+ switch (t->kind) {
+ case Type_Slice:
+ res = lb_slice_elem(p, x);
+ res = lb_emit_conv(p, res, tv.type);
+ break;
+ case Type_DynamicArray:
+ res = lb_dynamic_array_elem(p, x);
+ res = lb_emit_conv(p, res, tv.type);
+ break;
+ case Type_Basic:
+ if (t->Basic.kind == Basic_string) {
+ res = lb_string_elem(p, x);
+ res = lb_emit_conv(p, res, tv.type);
+ } else if (t->Basic.kind == Basic_cstring) {
+ res = lb_emit_conv(p, x, tv.type);
+ }
+ break;
+ case Type_Pointer:
+ case Type_MultiPointer:
+ res = lb_emit_conv(p, x, tv.type);
+ break;
+ }
+ GB_ASSERT(res.value != nullptr);
+ return res;
+ }
+
// "Intrinsics"