authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-05 17:19:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-05 17:19:01-07:00
log094336f07cdf42f2f79df5b190ccc0139412cfbc
treee74c6dcc8f3f4a72aee44ffcca1e6ca68d7dd4d1
parentdedde0d790a60522e073d78ce6bbb0714d50d7aa

add integer wrapping

see #46

7 files changed, 155 insertions(+), 78 deletions(-)

doc/langref.md+19-9
...@@ -181,19 +181,26 @@ x{}...@@ -181,19 +181,26 @@ x{}
181Type name C equivalent Description181Type name C equivalent Description
182182
183i8 int8_t signed 8-bit integer183i8 int8_t signed 8-bit integer
184u8 uint8_t unsigned 8-bit integer184u8 (none) unsigned 8-bit integer
185i16 int16_t signed 16-bit integer185i16 int16_t signed 16-bit integer
186u16 uint16_t unsigned 16-bit integer186u16 (none) unsigned 16-bit integer
187i32 int32_t signed 32-bit integer187i32 int32_t signed 32-bit integer
188u32 uint32_t unsigned 32-bit integer188u32 (none) unsigned 32-bit integer
189i64 int64_t signed 64-bit integer189i64 int64_t signed 64-bit integer
190u64 uint64_t unsigned 64-bit integer190u64 (none) unsigned 64-bit integer
191
192f32 float 32-bit IEE754 floating point
193f64 double 64-bit IEE754 floating point
194
195isize intptr_t signed pointer sized integer191isize intptr_t signed pointer sized integer
196usize uintptr_t unsigned pointer sized integer192usize (none) unsigned pointer sized integer
193
194i8w (none) wrapping signed 8-bit integer
195u8w uint8_t wrapping unsigned 8-bit integer
196i16w (none) wrapping signed 16-bit integer
197u16w uint16_t wrapping unsigned 16-bit integer
198i32w (none) wrapping signed 32-bit integer
199u32w uint32_t wrapping unsigned 32-bit integer
200i64w (none) wrapping signed 64-bit integer
201u64w uint64_t wrapping unsigned 64-bit integer
202isizew (none) wrapping signed pointer sized integer
203usizew uintptr_t wrapping unsigned pointer sized integer
197204
198c_short short for ABI compatibility with C205c_short short for ABI compatibility with C
199c_ushort unsigned short for ABI compatibility with C206c_ushort unsigned short for ABI compatibility with C
...@@ -205,6 +212,9 @@ c_longlong long long for ABI compatibility with C...@@ -205,6 +212,9 @@ c_longlong long long for ABI compatibility with C
205c_ulonglong unsigned long long for ABI compatibility with C212c_ulonglong unsigned long long for ABI compatibility with C
206c_long_double long double for ABI compatibility with C213c_long_double long double for ABI compatibility with C
207c_void void for ABI compatibility with C214c_void void for ABI compatibility with C
215
216f32 float 32-bit IEE754 floating point
217f64 double 64-bit IEE754 floating point
208```218```
209219
210### Boolean Type220### Boolean Type
doc/vim/syntax/zig.vim+3-1
...@@ -15,7 +15,9 @@ syn keyword zigRepeat while for...@@ -15,7 +15,9 @@ syn keyword zigRepeat while for
1515
16syn keyword zigConstant null undefined16syn keyword zigConstant null undefined
17syn keyword zigKeyword fn use17syn keyword zigKeyword fn use
18syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 void unreachable type error18syn keyword zigType bool f32 f64 void unreachable type error
19syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize
20syn keyword zigType i8w u8w i16w u16w i32w u32w i64w u64w isizew usizew
19syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong21syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong
2022
21syn keyword zigBoolean true false23syn keyword zigBoolean true false
src/all_types.hpp+3-2
...@@ -846,8 +846,9 @@ struct TypeTableEntryPointer {...@@ -846,8 +846,9 @@ struct TypeTableEntryPointer {
846};846};
847847
848struct TypeTableEntryInt {848struct TypeTableEntryInt {
849 bool is_signed;
850 int bit_count;849 int bit_count;
850 bool is_signed;
851 bool is_wrapping;
851};852};
852853
853struct TypeTableEntryFloat {854struct TypeTableEntryFloat {
...@@ -1157,7 +1158,7 @@ struct CodeGen {...@@ -1157,7 +1158,7 @@ struct CodeGen {
11571158
1158 struct {1159 struct {
1159 TypeTableEntry *entry_bool;1160 TypeTableEntry *entry_bool;
1160 TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]1161 TypeTableEntry *entry_int[2][2][4]; // [signed,unsigned][wrapping,nonwrapping][8,16,32,64]
1161 TypeTableEntry *entry_c_int[CIntTypeCount];1162 TypeTableEntry *entry_c_int[CIntTypeCount];
1162 TypeTableEntry *entry_c_long_double;1163 TypeTableEntry *entry_c_long_double;
1163 TypeTableEntry *entry_c_void;1164 TypeTableEntry *entry_c_void;
src/analyze.cpp+5-5
...@@ -206,7 +206,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {...@@ -206,7 +206,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
206}206}
207207
208TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {208TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
209 return get_int_type(g, false, bits_needed_for_unsigned(x));209 return get_int_type(g, false, false, bits_needed_for_unsigned(x));
210}210}
211211
212static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {212static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
...@@ -6453,7 +6453,7 @@ bool is_node_void_expr(AstNode *node) {...@@ -6453,7 +6453,7 @@ bool is_node_void_expr(AstNode *node) {
6453 return false;6453 return false;
6454}6454}
64556455
6456TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, int size_in_bits) {6456TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, bool is_wrapping, int size_in_bits) {
6457 int index;6457 int index;
6458 if (size_in_bits == 8) {6458 if (size_in_bits == 8) {
6459 index = 0;6459 index = 0;
...@@ -6466,11 +6466,11 @@ TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, int size_in_bits)...@@ -6466,11 +6466,11 @@ TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, int size_in_bits)
6466 } else {6466 } else {
6467 zig_unreachable();6467 zig_unreachable();
6468 }6468 }
6469 return &g->builtin_types.entry_int[is_signed ? 0 : 1][index];6469 return &g->builtin_types.entry_int[is_signed ? 0 : 1][is_wrapping ? 0 : 1][index];
6470}6470}
64716471
6472TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, int size_in_bits) {6472TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, bool is_wrapping, int size_in_bits) {
6473 return *get_int_type_ptr(g, is_signed, size_in_bits);6473 return *get_int_type_ptr(g, is_signed, is_wrapping, size_in_bits);
6474}6474}
64756475
6476TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {6476TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {
src/analyze.hpp+2-2
...@@ -18,8 +18,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -18,8 +18,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
18BlockContext *new_block_context(AstNode *node, BlockContext *parent);18BlockContext *new_block_context(AstNode *node, BlockContext *parent);
19Expr *get_resolved_expr(AstNode *node);19Expr *get_resolved_expr(AstNode *node);
20bool is_node_void_expr(AstNode *node);20bool is_node_void_expr(AstNode *node);
21TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, int size_in_bits);21TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, bool is_wrapping, int size_in_bits);
22TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, int size_in_bits);22TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, bool is_wrapping, int size_in_bits);
23TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);23TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
24TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);24TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);
25TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type);25TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type);
src/codegen.cpp+120-55
...@@ -338,6 +338,11 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) {...@@ -338,6 +338,11 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) {
338 return !g->is_release_build && !node->block_context->safety_off;338 return !g->is_release_build && !node->block_context->safety_off;
339}339}
340340
341static void gen_debug_safety_crash(CodeGen *g) {
342 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
343 LLVMBuildUnreachable(g->builder);
344}
345
341static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val,346static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val,
342 LLVMIntPredicate lower_pred, LLVMValueRef lower_value,347 LLVMIntPredicate lower_pred, LLVMValueRef lower_value,
343 LLVMIntPredicate upper_pred, LLVMValueRef upper_value)348 LLVMIntPredicate upper_pred, LLVMValueRef upper_value)
...@@ -362,8 +367,7 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ...@@ -362,8 +367,7 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ
362 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);367 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
363368
364 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);369 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);
365 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");370 gen_debug_safety_crash(g);
366 LLVMBuildUnreachable(g->builder);
367371
368 if (upper_value) {372 if (upper_value) {
369 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);373 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);
...@@ -1369,8 +1373,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -1369,8 +1373,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
1369 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);1373 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
13701374
1371 LLVMPositionBuilderAtEnd(g->builder, err_block);1375 LLVMPositionBuilderAtEnd(g->builder, err_block);
1372 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");1376 gen_debug_safety_crash(g);
1373 LLVMBuildUnreachable(g->builder);
13741377
1375 LLVMPositionBuilderAtEnd(g->builder, ok_block);1378 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1376 }1379 }
...@@ -1408,8 +1411,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -1408,8 +1411,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
1408 LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block);1411 LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block);
14091412
1410 LLVMPositionBuilderAtEnd(g->builder, null_block);1413 LLVMPositionBuilderAtEnd(g->builder, null_block);
1411 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");1414 gen_debug_safety_crash(g);
1412 LLVMBuildUnreachable(g->builder);
14131415
1414 LLVMPositionBuilderAtEnd(g->builder, ok_block);1416 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1415 }1417 }
...@@ -1429,6 +1431,28 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -1429,6 +1431,28 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
1429 zig_unreachable();1431 zig_unreachable();
1430}1432}
14311433
1434static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddSubMul op,
1435 LLVMValueRef val1, LLVMValueRef val2)
1436{
1437 LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op);
1438 LLVMValueRef params[] = {
1439 val1,
1440 val2,
1441 };
1442 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
1443 LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
1444 LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
1445 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail");
1446 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk");
1447 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
1448
1449 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1450 gen_debug_safety_crash(g);
1451
1452 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1453 return result;
1454}
1455
1432static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,1456static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
1433 LLVMValueRef val1, LLVMValueRef val2,1457 LLVMValueRef val1, LLVMValueRef val2,
1434 TypeTableEntry *op1_type, TypeTableEntry *op2_type,1458 TypeTableEntry *op1_type, TypeTableEntry *op2_type,
...@@ -1469,24 +1493,54 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,...@@ -1469,24 +1493,54 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
1469 set_debug_source_node(g, source_node);1493 set_debug_source_node(g, source_node);
1470 if (op1_type->id == TypeTableEntryIdFloat) {1494 if (op1_type->id == TypeTableEntryIdFloat) {
1471 return LLVMBuildFAdd(g->builder, val1, val2, "");1495 return LLVMBuildFAdd(g->builder, val1, val2, "");
1496 } else if (op1_type->id == TypeTableEntryIdInt) {
1497 if (op1_type->data.integral.is_wrapping) {
1498 return LLVMBuildAdd(g->builder, val1, val2, "");
1499 } else if (want_debug_safety(g, source_node)) {
1500 return gen_overflow_op(g, op1_type, AddSubMulAdd, val1, val2);
1501 } else if (op1_type->data.integral.is_signed) {
1502 return LLVMBuildNSWAdd(g->builder, val1, val2, "");
1503 } else {
1504 return LLVMBuildNUWAdd(g->builder, val1, val2, "");
1505 }
1472 } else {1506 } else {
1473 return LLVMBuildAdd(g->builder, val1, val2, "");1507 zig_unreachable();
1474 }1508 }
1475 case BinOpTypeSub:1509 case BinOpTypeSub:
1476 case BinOpTypeAssignMinus:1510 case BinOpTypeAssignMinus:
1477 set_debug_source_node(g, source_node);1511 set_debug_source_node(g, source_node);
1478 if (op1_type->id == TypeTableEntryIdFloat) {1512 if (op1_type->id == TypeTableEntryIdFloat) {
1479 return LLVMBuildFSub(g->builder, val1, val2, "");1513 return LLVMBuildFSub(g->builder, val1, val2, "");
1514 } else if (op1_type->id == TypeTableEntryIdInt) {
1515 if (op1_type->data.integral.is_wrapping) {
1516 return LLVMBuildSub(g->builder, val1, val2, "");
1517 } else if (want_debug_safety(g, source_node)) {
1518 return gen_overflow_op(g, op1_type, AddSubMulSub, val1, val2);
1519 } else if (op1_type->data.integral.is_signed) {
1520 return LLVMBuildNSWSub(g->builder, val1, val2, "");
1521 } else {
1522 return LLVMBuildNUWSub(g->builder, val1, val2, "");
1523 }
1480 } else {1524 } else {
1481 return LLVMBuildSub(g->builder, val1, val2, "");1525 zig_unreachable();
1482 }1526 }
1483 case BinOpTypeMult:1527 case BinOpTypeMult:
1484 case BinOpTypeAssignTimes:1528 case BinOpTypeAssignTimes:
1485 set_debug_source_node(g, source_node);1529 set_debug_source_node(g, source_node);
1486 if (op1_type->id == TypeTableEntryIdFloat) {1530 if (op1_type->id == TypeTableEntryIdFloat) {
1487 return LLVMBuildFMul(g->builder, val1, val2, "");1531 return LLVMBuildFMul(g->builder, val1, val2, "");
1532 } else if (op1_type->id == TypeTableEntryIdInt) {
1533 if (op1_type->data.integral.is_wrapping) {
1534 return LLVMBuildMul(g->builder, val1, val2, "");
1535 } else if (want_debug_safety(g, source_node)) {
1536 return gen_overflow_op(g, op1_type, AddSubMulMul, val1, val2);
1537 } else if (op1_type->data.integral.is_signed) {
1538 return LLVMBuildNSWMul(g->builder, val1, val2, "");
1539 } else {
1540 return LLVMBuildNUWMul(g->builder, val1, val2, "");
1541 }
1488 } else {1542 } else {
1489 return LLVMBuildMul(g->builder, val1, val2, "");1543 zig_unreachable();
1490 }1544 }
1491 case BinOpTypeDiv:1545 case BinOpTypeDiv:
1492 case BinOpTypeAssignDiv:1546 case BinOpTypeAssignDiv:
...@@ -2472,9 +2526,10 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {...@@ -2472,9 +2526,10 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
2472 assert(node->data.container_init_expr.entries.length == 0);2526 assert(node->data.container_init_expr.entries.length == 0);
2473 set_debug_source_node(g, node);2527 set_debug_source_node(g, node);
2474 if (want_debug_safety(g, node)) {2528 if (want_debug_safety(g, node)) {
2475 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");2529 gen_debug_safety_crash(g);
2530 } else {
2531 LLVMBuildUnreachable(g->builder);
2476 }2532 }
2477 LLVMBuildUnreachable(g->builder);
2478 return nullptr;2533 return nullptr;
2479 } else if (type_entry->id == TypeTableEntryIdVoid) {2534 } else if (type_entry->id == TypeTableEntryIdVoid) {
2480 assert(node->data.container_init_expr.entries.length == 0);2535 assert(node->data.container_init_expr.entries.length == 0);
...@@ -2983,7 +3038,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {...@@ -2983,7 +3038,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
2983 set_debug_source_node(g, prong_expr);3038 set_debug_source_node(g, prong_expr);
2984 LLVMBuildBr(g->builder, end_block);3039 LLVMBuildBr(g->builder, end_block);
2985 incoming_values.append(prong_val);3040 incoming_values.append(prong_val);
2986 incoming_blocks.append(prong_block);3041 incoming_blocks.append(LLVMGetInsertBlock(g->builder));
2987 }3042 }
2988 }3043 }
29893044
...@@ -2991,9 +3046,10 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {...@@ -2991,9 +3046,10 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
2991 LLVMPositionBuilderAtEnd(g->builder, else_block);3046 LLVMPositionBuilderAtEnd(g->builder, else_block);
2992 set_debug_source_node(g, node);3047 set_debug_source_node(g, node);
2993 if (want_debug_safety(g, node)) {3048 if (want_debug_safety(g, node)) {
2994 LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");3049 gen_debug_safety_crash(g);
3050 } else {
3051 LLVMBuildUnreachable(g->builder);
2995 }3052 }
2996 LLVMBuildUnreachable(g->builder);
2997 }3053 }
29983054
2999 if (end_unreachable) {3055 if (end_unreachable) {
...@@ -3776,6 +3832,18 @@ static const CIntTypeInfo c_int_type_infos[] = {...@@ -3776,6 +3832,18 @@ static const CIntTypeInfo c_int_type_infos[] = {
3776 {CIntTypeULongLong, "c_ulonglong", false},3832 {CIntTypeULongLong, "c_ulonglong", false},
3777};3833};
37783834
3835struct SignWrap {
3836 bool is_signed;
3837 bool is_wrapping;
3838};
3839
3840static const SignWrap sign_wrap_list[] = {
3841 {false, false},
3842 {false, true},
3843 {true, false},
3844 {true, true},
3845};
3846
3779static void define_builtin_types(CodeGen *g) {3847static void define_builtin_types(CodeGen *g) {
3780 {3848 {
3781 // if this type is anywhere in the AST, we should never hit codegen.3849 // if this type is anywhere in the AST, we should never hit codegen.
...@@ -3812,17 +3880,20 @@ static void define_builtin_types(CodeGen *g) {...@@ -3812,17 +3880,20 @@ static void define_builtin_types(CodeGen *g) {
3812 g->builtin_types.entry_undef = entry;3880 g->builtin_types.entry_undef = entry;
3813 }3881 }
38143882
3815 for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) {3883 for (int int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) {
3816 int size_in_bits = int_sizes_in_bits[i];3884 int size_in_bits = int_sizes_in_bits[int_size_i];
3817 bool is_signed = true;3885 for (int sign_wrap_i = 0; sign_wrap_i < array_length(sign_wrap_list); sign_wrap_i += 1) {
3818 for (;;) {3886 bool is_signed = sign_wrap_list[sign_wrap_i].is_signed;
3887 bool is_wrapping = sign_wrap_list[sign_wrap_i].is_wrapping;
3888
3819 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3889 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3820 entry->type_ref = LLVMIntType(size_in_bits);3890 entry->type_ref = LLVMIntType(size_in_bits);
3821 entry->deep_const = true;3891 entry->deep_const = true;
38223892
3823 const char u_or_i = is_signed ? 'i' : 'u';3893 const char u_or_i = is_signed ? 'i' : 'u';
3894 const char *w_or_none = is_wrapping ? "w" : "";
3824 buf_resize(&entry->name, 0);3895 buf_resize(&entry->name, 0);
3825 buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits);3896 buf_appendf(&entry->name, "%c%d%s", u_or_i, size_in_bits, w_or_none);
38263897
3827 unsigned dwarf_tag;3898 unsigned dwarf_tag;
3828 if (is_signed) {3899 if (is_signed) {
...@@ -3844,16 +3915,11 @@ static void define_builtin_types(CodeGen *g) {...@@ -3844,16 +3915,11 @@ static void define_builtin_types(CodeGen *g) {
3844 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3915 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3845 debug_size_in_bits, debug_align_in_bits, dwarf_tag);3916 debug_size_in_bits, debug_align_in_bits, dwarf_tag);
3846 entry->data.integral.is_signed = is_signed;3917 entry->data.integral.is_signed = is_signed;
3918 entry->data.integral.is_wrapping = is_wrapping;
3847 entry->data.integral.bit_count = size_in_bits;3919 entry->data.integral.bit_count = size_in_bits;
3848 g->primitive_type_table.put(&entry->name, entry);3920 g->primitive_type_table.put(&entry->name, entry);
38493921
3850 get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry;3922 get_int_type_ptr(g, is_signed, is_wrapping, size_in_bits)[0] = entry;
3851
3852 if (!is_signed) {
3853 break;
3854 } else {
3855 is_signed = false;
3856 }
3857 }3923 }
3858 }3924 }
38593925
...@@ -3875,6 +3941,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3875,6 +3941,7 @@ static void define_builtin_types(CodeGen *g) {
3875 debug_align_in_bits,3941 debug_align_in_bits,
3876 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());3942 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
3877 entry->data.integral.is_signed = is_signed;3943 entry->data.integral.is_signed = is_signed;
3944 entry->data.integral.is_wrapping = !is_signed;
3878 entry->data.integral.bit_count = size_in_bits;3945 entry->data.integral.bit_count = size_in_bits;
3879 g->primitive_type_table.put(&entry->name, entry);3946 g->primitive_type_table.put(&entry->name, entry);
38803947
...@@ -3895,29 +3962,22 @@ static void define_builtin_types(CodeGen *g) {...@@ -3895,29 +3962,22 @@ static void define_builtin_types(CodeGen *g) {
3895 g->builtin_types.entry_bool = entry;3962 g->builtin_types.entry_bool = entry;
3896 g->primitive_type_table.put(&entry->name, entry);3963 g->primitive_type_table.put(&entry->name, entry);
3897 }3964 }
3898 {
3899 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3900 entry->deep_const = true;
3901 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3902 buf_init_from_str(&entry->name, "isize");
3903 entry->data.integral.is_signed = true;
3904 entry->data.integral.bit_count = g->pointer_size_bytes * 8;
39053965
3906 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);3966 for (int sign_wrap_i = 0; sign_wrap_i < array_length(sign_wrap_list); sign_wrap_i += 1) {
3907 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);3967 bool is_signed = sign_wrap_list[sign_wrap_i].is_signed;
3908 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3968 bool is_wrapping = sign_wrap_list[sign_wrap_i].is_wrapping;
3909 debug_size_in_bits,3969
3910 debug_align_in_bits,
3911 LLVMZigEncoding_DW_ATE_signed());
3912 g->builtin_types.entry_isize = entry;
3913 g->primitive_type_table.put(&entry->name, entry);
3914 }
3915 {
3916 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3970 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3917 entry->deep_const = true;3971 entry->deep_const = true;
3918 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3972 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3919 buf_init_from_str(&entry->name, "usize");3973
3920 entry->data.integral.is_signed = false;3974 const char u_or_i = is_signed ? 'i' : 'u';
3975 const char *w_or_none = is_wrapping ? "w" : "";
3976 buf_resize(&entry->name, 0);
3977 buf_appendf(&entry->name, "%csize%s", u_or_i, w_or_none);
3978
3979 entry->data.integral.is_signed = is_signed;
3980 entry->data.integral.is_wrapping = is_wrapping;
3921 entry->data.integral.bit_count = g->pointer_size_bytes * 8;3981 entry->data.integral.bit_count = g->pointer_size_bytes * 8;
39223982
3923 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);3983 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
...@@ -3925,9 +3985,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -3925,9 +3985,14 @@ static void define_builtin_types(CodeGen *g) {
3925 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),3985 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
3926 debug_size_in_bits,3986 debug_size_in_bits,
3927 debug_align_in_bits,3987 debug_align_in_bits,
3928 LLVMZigEncoding_DW_ATE_unsigned());3988 is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned());
3929 g->builtin_types.entry_usize = entry;
3930 g->primitive_type_table.put(&entry->name, entry);3989 g->primitive_type_table.put(&entry->name, entry);
3990
3991 if (is_signed && !is_wrapping) {
3992 g->builtin_types.entry_isize = entry;
3993 } else if (!is_signed && !is_wrapping) {
3994 g->builtin_types.entry_usize = entry;
3995 }
3931 }3996 }
3932 {3997 {
3933 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3998 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
...@@ -4009,14 +4074,14 @@ static void define_builtin_types(CodeGen *g) {...@@ -4009,14 +4074,14 @@ static void define_builtin_types(CodeGen *g) {
4009 g->primitive_type_table.put(&entry->name, entry);4074 g->primitive_type_table.put(&entry->name, entry);
4010 }4075 }
40114076
4012 g->builtin_types.entry_u8 = get_int_type(g, false, 8);4077 g->builtin_types.entry_u8 = get_int_type(g, false, false, 8);
4013 g->builtin_types.entry_u16 = get_int_type(g, false, 16);4078 g->builtin_types.entry_u16 = get_int_type(g, false, false, 16);
4014 g->builtin_types.entry_u32 = get_int_type(g, false, 32);4079 g->builtin_types.entry_u32 = get_int_type(g, false, false, 32);
4015 g->builtin_types.entry_u64 = get_int_type(g, false, 64);4080 g->builtin_types.entry_u64 = get_int_type(g, false, false, 64);
4016 g->builtin_types.entry_i8 = get_int_type(g, true, 8);4081 g->builtin_types.entry_i8 = get_int_type(g, true, false, 8);
4017 g->builtin_types.entry_i16 = get_int_type(g, true, 16);4082 g->builtin_types.entry_i16 = get_int_type(g, true, false, 16);
4018 g->builtin_types.entry_i32 = get_int_type(g, true, 32);4083 g->builtin_types.entry_i32 = get_int_type(g, true, false, 32);
4019 g->builtin_types.entry_i64 = get_int_type(g, true, 64);4084 g->builtin_types.entry_i64 = get_int_type(g, true, false, 64);
40204085
4021 {4086 {
4022 g->builtin_types.entry_c_void = get_typedecl_type(g, "c_void", g->builtin_types.entry_u8);4087 g->builtin_types.entry_c_void = get_typedecl_type(g, "c_void", g->builtin_types.entry_u8);
std/rand.zig+3-4
...@@ -13,11 +13,10 @@ pub struct Rand {...@@ -13,11 +13,10 @@ pub struct Rand {
13 r.index = 0;13 r.index = 0;
14 r.array[0] = seed;14 r.array[0] = seed;
15 var i : isize = 1;15 var i : isize = 1;
16 var prev_value: u64 = seed;16 var prev_value: u64w = seed;
17 while (i < ARRAY_SIZE) {17 while (i < ARRAY_SIZE; i += 1) {
18 r.array[i] = u32((prev_value ^ (prev_value << 30)) * 0x6c078965 + u32(i));18 r.array[i] = u32((prev_value ^ (prev_value << 30)) * 0x6c078965 + u64w(i));
19 prev_value = r.array[i];19 prev_value = r.array[i];
20 i += 1;
21 }20 }
22 return r;21 return r;
23 }22 }