| ... | ... | @@ -184,14 +184,28 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 184 | 184 | case BuiltinFnIdInvalid: |
| 185 | 185 | case BuiltinFnIdTypeof: |
| 186 | 186 | zig_unreachable(); |
| 187 | | case BuiltinFnIdArithmeticWithOverflow: |
| 187 | case BuiltinFnIdAddWithOverflow: |
| 188 | case BuiltinFnIdSubWithOverflow: |
| 189 | case BuiltinFnIdMulWithOverflow: |
| 188 | 190 | { |
| 189 | 191 | int fn_call_param_count = node->data.fn_call_expr.params.length; |
| 190 | | assert(fn_call_param_count == 3); |
| 192 | assert(fn_call_param_count == 4); |
| 193 | |
| 194 | TypeTableEntry *int_type = get_type_for_type_node(node->data.fn_call_expr.params.at(0)); |
| 195 | LLVMValueRef fn_val; |
| 196 | if (builtin_fn->id == BuiltinFnIdAddWithOverflow) { |
| 197 | fn_val = int_type->data.integral.add_with_overflow_fn; |
| 198 | } else if (builtin_fn->id == BuiltinFnIdSubWithOverflow) { |
| 199 | fn_val = int_type->data.integral.sub_with_overflow_fn; |
| 200 | } else if (builtin_fn->id == BuiltinFnIdMulWithOverflow) { |
| 201 | fn_val = int_type->data.integral.mul_with_overflow_fn; |
| 202 | } else { |
| 203 | zig_unreachable(); |
| 204 | } |
| 191 | 205 | |
| 192 | | LLVMValueRef op1 = gen_expr(g, node->data.fn_call_expr.params.at(0)); |
| 193 | | LLVMValueRef op2 = gen_expr(g, node->data.fn_call_expr.params.at(1)); |
| 194 | | LLVMValueRef ptr_result = gen_expr(g, node->data.fn_call_expr.params.at(2)); |
| 206 | LLVMValueRef op1 = gen_expr(g, node->data.fn_call_expr.params.at(1)); |
| 207 | LLVMValueRef op2 = gen_expr(g, node->data.fn_call_expr.params.at(2)); |
| 208 | LLVMValueRef ptr_result = gen_expr(g, node->data.fn_call_expr.params.at(3)); |
| 195 | 209 | |
| 196 | 210 | LLVMValueRef params[] = { |
| 197 | 211 | op1, |
| ... | ... | @@ -199,7 +213,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 199 | 213 | }; |
| 200 | 214 | |
| 201 | 215 | add_debug_source_node(g, node); |
| 202 | | LLVMValueRef result_struct = LLVMBuildCall(g->builder, builtin_fn->fn_val, params, 2, ""); |
| 216 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 203 | 217 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 204 | 218 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| 205 | 219 | LLVMBuildStore(g->builder, result, ptr_result); |
| ... | ... | @@ -2184,6 +2198,35 @@ static void do_code_gen(CodeGen *g) { |
| 2184 | 2198 | #endif |
| 2185 | 2199 | } |
| 2186 | 2200 | |
| 2201 | static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_entry, |
| 2202 | const char *signed_name, const char *unsigned_name) |
| 2203 | { |
| 2204 | const char *signed_str = type_entry->data.integral.is_signed ? signed_name : unsigned_name; |
| 2205 | Buf *llvm_name = buf_sprintf("llvm.%s.with.overflow.i%" PRIu64, signed_str, type_entry->size_in_bits); |
| 2206 | |
| 2207 | LLVMTypeRef return_elem_types[] = { |
| 2208 | type_entry->type_ref, |
| 2209 | LLVMInt1Type(), |
| 2210 | }; |
| 2211 | LLVMTypeRef param_types[] = { |
| 2212 | type_entry->type_ref, |
| 2213 | type_entry->type_ref, |
| 2214 | }; |
| 2215 | LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false); |
| 2216 | LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false); |
| 2217 | LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(llvm_name), fn_type); |
| 2218 | assert(LLVMGetIntrinsicID(fn_val)); |
| 2219 | return fn_val; |
| 2220 | } |
| 2221 | |
| 2222 | static void add_int_overflow_fns(CodeGen *g, TypeTableEntry *type_entry) { |
| 2223 | assert(type_entry->id == TypeTableEntryIdInt); |
| 2224 | |
| 2225 | type_entry->data.integral.add_with_overflow_fn = get_arithmetic_overflow_fn(g, type_entry, "sadd", "uadd"); |
| 2226 | type_entry->data.integral.sub_with_overflow_fn = get_arithmetic_overflow_fn(g, type_entry, "ssub", "usub"); |
| 2227 | type_entry->data.integral.mul_with_overflow_fn = get_arithmetic_overflow_fn(g, type_entry, "smul", "umul"); |
| 2228 | } |
| 2229 | |
| 2187 | 2230 | static const NumLit num_lit_kinds[] = { |
| 2188 | 2231 | NumLitF32, |
| 2189 | 2232 | NumLitF64, |
| ... | ... | @@ -2198,6 +2241,13 @@ static const NumLit num_lit_kinds[] = { |
| 2198 | 2241 | NumLitI64, |
| 2199 | 2242 | }; |
| 2200 | 2243 | |
| 2244 | static const int int_sizes_in_bits[] = { |
| 2245 | 8, |
| 2246 | 16, |
| 2247 | 32, |
| 2248 | 64, |
| 2249 | }; |
| 2250 | |
| 2201 | 2251 | static void define_builtin_types(CodeGen *g) { |
| 2202 | 2252 | { |
| 2203 | 2253 | // if this type is anywhere in the AST, we should never hit codegen. |
| ... | ... | @@ -2219,6 +2269,37 @@ static void define_builtin_types(CodeGen *g) { |
| 2219 | 2269 | g->num_lit_types[i] = entry; |
| 2220 | 2270 | } |
| 2221 | 2271 | |
| 2272 | for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) { |
| 2273 | int size_in_bits = int_sizes_in_bits[i]; |
| 2274 | bool is_signed = true; |
| 2275 | for (;;) { |
| 2276 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2277 | entry->type_ref = LLVMIntType(size_in_bits); |
| 2278 | |
| 2279 | const char u_or_i = is_signed ? 'i' : 'u'; |
| 2280 | buf_resize(&entry->name, 0); |
| 2281 | buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits); |
| 2282 | |
| 2283 | entry->size_in_bits = size_in_bits; |
| 2284 | entry->align_in_bits = size_in_bits; |
| 2285 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2286 | entry->size_in_bits, entry->align_in_bits, |
| 2287 | is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned()); |
| 2288 | entry->data.integral.is_signed = is_signed; |
| 2289 | g->primitive_type_table.put(&entry->name, entry); |
| 2290 | |
| 2291 | get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry; |
| 2292 | |
| 2293 | add_int_overflow_fns(g, entry); |
| 2294 | |
| 2295 | if (!is_signed) { |
| 2296 | break; |
| 2297 | } else { |
| 2298 | is_signed = false; |
| 2299 | } |
| 2300 | } |
| 2301 | } |
| 2302 | |
| 2222 | 2303 | { |
| 2223 | 2304 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool); |
| 2224 | 2305 | entry->type_ref = LLVMInt1Type(); |
| ... | ... | @@ -2231,110 +2312,6 @@ static void define_builtin_types(CodeGen *g) { |
| 2231 | 2312 | g->builtin_types.entry_bool = entry; |
| 2232 | 2313 | g->primitive_type_table.put(&entry->name, entry); |
| 2233 | 2314 | } |
| 2234 | | { |
| 2235 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2236 | | entry->type_ref = LLVMInt8Type(); |
| 2237 | | buf_init_from_str(&entry->name, "u8"); |
| 2238 | | entry->size_in_bits = 8; |
| 2239 | | entry->align_in_bits = 8; |
| 2240 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2241 | | entry->size_in_bits, entry->align_in_bits, |
| 2242 | | LLVMZigEncoding_DW_ATE_unsigned()); |
| 2243 | | g->builtin_types.entry_u8 = entry; |
| 2244 | | g->primitive_type_table.put(&entry->name, entry); |
| 2245 | | } |
| 2246 | | { |
| 2247 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2248 | | entry->type_ref = LLVMInt16Type(); |
| 2249 | | buf_init_from_str(&entry->name, "u16"); |
| 2250 | | entry->size_in_bits = 16; |
| 2251 | | entry->align_in_bits = 16; |
| 2252 | | entry->data.integral.is_signed = false; |
| 2253 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2254 | | entry->size_in_bits, entry->align_in_bits, |
| 2255 | | LLVMZigEncoding_DW_ATE_unsigned()); |
| 2256 | | g->builtin_types.entry_u16 = entry; |
| 2257 | | g->primitive_type_table.put(&entry->name, entry); |
| 2258 | | } |
| 2259 | | { |
| 2260 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2261 | | entry->type_ref = LLVMInt32Type(); |
| 2262 | | buf_init_from_str(&entry->name, "u32"); |
| 2263 | | entry->size_in_bits = 32; |
| 2264 | | entry->align_in_bits = 32; |
| 2265 | | entry->data.integral.is_signed = false; |
| 2266 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2267 | | entry->size_in_bits, entry->align_in_bits, |
| 2268 | | LLVMZigEncoding_DW_ATE_unsigned()); |
| 2269 | | g->builtin_types.entry_u32 = entry; |
| 2270 | | g->primitive_type_table.put(&entry->name, entry); |
| 2271 | | } |
| 2272 | | { |
| 2273 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2274 | | entry->type_ref = LLVMInt64Type(); |
| 2275 | | buf_init_from_str(&entry->name, "u64"); |
| 2276 | | entry->size_in_bits = 64; |
| 2277 | | entry->align_in_bits = 64; |
| 2278 | | entry->data.integral.is_signed = false; |
| 2279 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2280 | | entry->size_in_bits, entry->align_in_bits, |
| 2281 | | LLVMZigEncoding_DW_ATE_unsigned()); |
| 2282 | | g->builtin_types.entry_u64 = entry; |
| 2283 | | g->primitive_type_table.put(&entry->name, entry); |
| 2284 | | } |
| 2285 | | g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true); |
| 2286 | | { |
| 2287 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2288 | | entry->type_ref = LLVMInt8Type(); |
| 2289 | | buf_init_from_str(&entry->name, "i8"); |
| 2290 | | entry->size_in_bits = 8; |
| 2291 | | entry->align_in_bits = 8; |
| 2292 | | entry->data.integral.is_signed = true; |
| 2293 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2294 | | entry->size_in_bits, entry->align_in_bits, |
| 2295 | | LLVMZigEncoding_DW_ATE_signed()); |
| 2296 | | g->builtin_types.entry_i8 = entry; |
| 2297 | | g->primitive_type_table.put(&entry->name, entry); |
| 2298 | | } |
| 2299 | | { |
| 2300 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2301 | | entry->type_ref = LLVMInt16Type(); |
| 2302 | | buf_init_from_str(&entry->name, "i16"); |
| 2303 | | entry->size_in_bits = 16; |
| 2304 | | entry->align_in_bits = 16; |
| 2305 | | entry->data.integral.is_signed = true; |
| 2306 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2307 | | entry->size_in_bits, entry->align_in_bits, |
| 2308 | | LLVMZigEncoding_DW_ATE_signed()); |
| 2309 | | g->builtin_types.entry_i16 = entry; |
| 2310 | | g->primitive_type_table.put(&entry->name, entry); |
| 2311 | | } |
| 2312 | | { |
| 2313 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2314 | | entry->type_ref = LLVMInt32Type(); |
| 2315 | | buf_init_from_str(&entry->name, "i32"); |
| 2316 | | entry->size_in_bits = 32; |
| 2317 | | entry->align_in_bits = 32; |
| 2318 | | entry->data.integral.is_signed = true; |
| 2319 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2320 | | entry->size_in_bits, entry->align_in_bits, |
| 2321 | | LLVMZigEncoding_DW_ATE_signed()); |
| 2322 | | g->builtin_types.entry_i32 = entry; |
| 2323 | | g->primitive_type_table.put(&entry->name, entry); |
| 2324 | | } |
| 2325 | | { |
| 2326 | | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2327 | | entry->type_ref = LLVMInt64Type(); |
| 2328 | | buf_init_from_str(&entry->name, "i64"); |
| 2329 | | entry->size_in_bits = 64; |
| 2330 | | entry->align_in_bits = 64; |
| 2331 | | entry->data.integral.is_signed = true; |
| 2332 | | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2333 | | entry->size_in_bits, entry->align_in_bits, |
| 2334 | | LLVMZigEncoding_DW_ATE_signed()); |
| 2335 | | g->builtin_types.entry_i64 = entry; |
| 2336 | | g->primitive_type_table.put(&entry->name, entry); |
| 2337 | | } |
| 2338 | 2315 | { |
| 2339 | 2316 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 2340 | 2317 | entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); |
| ... | ... | @@ -2342,6 +2319,12 @@ static void define_builtin_types(CodeGen *g) { |
| 2342 | 2319 | entry->size_in_bits = g->pointer_size_bytes * 8; |
| 2343 | 2320 | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 2344 | 2321 | entry->data.integral.is_signed = true; |
| 2322 | |
| 2323 | TypeTableEntry *fixed_width_entry = get_int_type(g, entry->data.integral.is_signed, entry->size_in_bits); |
| 2324 | entry->data.integral.add_with_overflow_fn = fixed_width_entry->data.integral.add_with_overflow_fn; |
| 2325 | entry->data.integral.sub_with_overflow_fn = fixed_width_entry->data.integral.sub_with_overflow_fn; |
| 2326 | entry->data.integral.mul_with_overflow_fn = fixed_width_entry->data.integral.mul_with_overflow_fn; |
| 2327 | |
| 2345 | 2328 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2346 | 2329 | entry->size_in_bits, entry->align_in_bits, |
| 2347 | 2330 | LLVMZigEncoding_DW_ATE_signed()); |
| ... | ... | @@ -2355,6 +2338,12 @@ static void define_builtin_types(CodeGen *g) { |
| 2355 | 2338 | entry->size_in_bits = g->pointer_size_bytes * 8; |
| 2356 | 2339 | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 2357 | 2340 | entry->data.integral.is_signed = false; |
| 2341 | |
| 2342 | TypeTableEntry *fixed_width_entry = get_int_type(g, entry->data.integral.is_signed, entry->size_in_bits); |
| 2343 | entry->data.integral.add_with_overflow_fn = fixed_width_entry->data.integral.add_with_overflow_fn; |
| 2344 | entry->data.integral.sub_with_overflow_fn = fixed_width_entry->data.integral.sub_with_overflow_fn; |
| 2345 | entry->data.integral.mul_with_overflow_fn = fixed_width_entry->data.integral.mul_with_overflow_fn; |
| 2346 | |
| 2358 | 2347 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 2359 | 2348 | entry->size_in_bits, entry->align_in_bits, |
| 2360 | 2349 | LLVMZigEncoding_DW_ATE_unsigned()); |
| ... | ... | @@ -2403,55 +2392,20 @@ static void define_builtin_types(CodeGen *g) { |
| 2403 | 2392 | g->builtin_types.entry_unreachable = entry; |
| 2404 | 2393 | g->primitive_type_table.put(&entry->name, entry); |
| 2405 | 2394 | } |
| 2406 | | } |
| 2407 | | |
| 2408 | | static void define_builtin_fns_int(CodeGen *g, TypeTableEntry *type_entry) { |
| 2409 | | assert(type_entry->id == TypeTableEntryIdInt); |
| 2410 | | struct OverflowFn { |
| 2411 | | const char *bare_name; |
| 2412 | | const char *signed_name; |
| 2413 | | const char *unsigned_name; |
| 2414 | | }; |
| 2415 | | OverflowFn overflow_fns[] = { |
| 2416 | | {"add", "sadd", "uadd"}, |
| 2417 | | {"sub", "ssub", "usub"}, |
| 2418 | | {"mul", "smul", "umul"}, |
| 2419 | | }; |
| 2420 | | for (size_t i = 0; i < sizeof(overflow_fns)/sizeof(overflow_fns[0]); i += 1) { |
| 2421 | | OverflowFn *overflow_fn = &overflow_fns[i]; |
| 2422 | | BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1); |
| 2423 | | buf_resize(&builtin_fn->name, 0); |
| 2424 | | buf_appendf(&builtin_fn->name, "%s_with_overflow_%s", overflow_fn->bare_name, buf_ptr(&type_entry->name)); |
| 2425 | | builtin_fn->id = BuiltinFnIdArithmeticWithOverflow; |
| 2426 | | builtin_fn->return_type = g->builtin_types.entry_bool; |
| 2427 | | builtin_fn->param_count = 3; |
| 2428 | | builtin_fn->param_types = allocate<TypeTableEntry *>(builtin_fn->param_count); |
| 2429 | | builtin_fn->param_types[0] = type_entry; |
| 2430 | | builtin_fn->param_types[1] = type_entry; |
| 2431 | | builtin_fn->param_types[2] = get_pointer_to_type(g, type_entry, false); |
| 2432 | 2395 | |
| 2396 | g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, get_int_type(g, false, 8), true); |
| 2433 | 2397 | |
| 2434 | | const char *signed_str = type_entry->data.integral.is_signed ? |
| 2435 | | overflow_fn->signed_name : overflow_fn->unsigned_name; |
| 2436 | | Buf *llvm_name = buf_sprintf("llvm.%s.with.overflow.i%" PRIu64, signed_str, type_entry->size_in_bits); |
| 2437 | | |
| 2438 | | LLVMTypeRef return_elem_types[] = { |
| 2439 | | type_entry->type_ref, |
| 2440 | | LLVMInt1Type(), |
| 2441 | | }; |
| 2442 | | LLVMTypeRef param_types[] = { |
| 2443 | | type_entry->type_ref, |
| 2444 | | type_entry->type_ref, |
| 2445 | | }; |
| 2446 | | LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false); |
| 2447 | | LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false); |
| 2448 | | builtin_fn->fn_val = LLVMAddFunction(g->module, buf_ptr(llvm_name), fn_type); |
| 2449 | | assert(LLVMGetIntrinsicID(builtin_fn->fn_val)); |
| 2450 | | |
| 2451 | | g->builtin_fn_table.put(&builtin_fn->name, builtin_fn); |
| 2452 | | } |
| 2398 | g->builtin_types.entry_u8 = get_int_type(g, false, 8); |
| 2399 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); |
| 2400 | g->builtin_types.entry_u32 = get_int_type(g, false, 32); |
| 2401 | g->builtin_types.entry_u64 = get_int_type(g, false, 64); |
| 2402 | g->builtin_types.entry_i8 = get_int_type(g, true, 8); |
| 2403 | g->builtin_types.entry_i16 = get_int_type(g, true, 16); |
| 2404 | g->builtin_types.entry_i32 = get_int_type(g, true, 32); |
| 2405 | g->builtin_types.entry_i64 = get_int_type(g, true, 64); |
| 2453 | 2406 | } |
| 2454 | 2407 | |
| 2408 | |
| 2455 | 2409 | static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name) { |
| 2456 | 2410 | BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1); |
| 2457 | 2411 | buf_init_from_str(&builtin_fn->name, name); |
| ... | ... | @@ -2460,24 +2414,14 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char |
| 2460 | 2414 | return builtin_fn; |
| 2461 | 2415 | } |
| 2462 | 2416 | |
| 2463 | | static BuiltinFnEntry *create_one_arg_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name) { |
| 2417 | static BuiltinFnEntry *create_builtin_fn_with_arg_count(CodeGen *g, BuiltinFnId id, const char *name, int count) { |
| 2464 | 2418 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, id, name); |
| 2465 | | builtin_fn->return_type = nullptr; // manually determined later |
| 2466 | | builtin_fn->param_count = 1; |
| 2467 | | builtin_fn->param_types = allocate<TypeTableEntry *>(builtin_fn->param_count); |
| 2468 | | builtin_fn->param_types[0] = nullptr; // manually checked later |
| 2419 | builtin_fn->param_count = count; |
| 2420 | builtin_fn->param_types = allocate<TypeTableEntry *>(count); |
| 2469 | 2421 | return builtin_fn; |
| 2470 | 2422 | } |
| 2471 | 2423 | |
| 2472 | 2424 | static void define_builtin_fns(CodeGen *g) { |
| 2473 | | define_builtin_fns_int(g, g->builtin_types.entry_u8); |
| 2474 | | define_builtin_fns_int(g, g->builtin_types.entry_u16); |
| 2475 | | define_builtin_fns_int(g, g->builtin_types.entry_u32); |
| 2476 | | define_builtin_fns_int(g, g->builtin_types.entry_u64); |
| 2477 | | define_builtin_fns_int(g, g->builtin_types.entry_i8); |
| 2478 | | define_builtin_fns_int(g, g->builtin_types.entry_i16); |
| 2479 | | define_builtin_fns_int(g, g->builtin_types.entry_i32); |
| 2480 | | define_builtin_fns_int(g, g->builtin_types.entry_i64); |
| 2481 | 2425 | { |
| 2482 | 2426 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy"); |
| 2483 | 2427 | builtin_fn->return_type = g->builtin_types.entry_void; |
| ... | ... | @@ -2524,11 +2468,14 @@ static void define_builtin_fns(CodeGen *g) { |
| 2524 | 2468 | |
| 2525 | 2469 | g->memset_fn_val = builtin_fn->fn_val; |
| 2526 | 2470 | } |
| 2527 | | create_one_arg_builtin_fn(g, BuiltinFnIdSizeof, "sizeof"); |
| 2528 | | create_one_arg_builtin_fn(g, BuiltinFnIdMaxValue, "max_value"); |
| 2529 | | create_one_arg_builtin_fn(g, BuiltinFnIdMinValue, "min_value"); |
| 2530 | | create_one_arg_builtin_fn(g, BuiltinFnIdValueCount, "value_count"); |
| 2531 | | create_one_arg_builtin_fn(g, BuiltinFnIdTypeof, "typeof"); |
| 2471 | create_builtin_fn_with_arg_count(g, BuiltinFnIdSizeof, "sizeof", 1); |
| 2472 | create_builtin_fn_with_arg_count(g, BuiltinFnIdMaxValue, "max_value", 1); |
| 2473 | create_builtin_fn_with_arg_count(g, BuiltinFnIdMinValue, "min_value", 1); |
| 2474 | create_builtin_fn_with_arg_count(g, BuiltinFnIdValueCount, "value_count", 1); |
| 2475 | create_builtin_fn_with_arg_count(g, BuiltinFnIdTypeof, "typeof", 1); |
| 2476 | create_builtin_fn_with_arg_count(g, BuiltinFnIdAddWithOverflow, "add_with_overflow", 4); |
| 2477 | create_builtin_fn_with_arg_count(g, BuiltinFnIdSubWithOverflow, "sub_with_overflow", 4); |
| 2478 | create_builtin_fn_with_arg_count(g, BuiltinFnIdMulWithOverflow, "mul_with_overflow", 4); |
| 2532 | 2479 | } |
| 2533 | 2480 | |
| 2534 | 2481 | |