authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-21 15:36:25-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-21 15:36:25-05:00
loga2257e4b81764f8603a39b74eae3622651ec7d6b
tree6e046fee9d846528f4259926d49e4c1ec8208df4
parent052cd44588a94550a431adc6d1ff5af7e4439c88

IR: implement setFnVisible builtin


6 files changed, 371 insertions(+), 305 deletions(-)

src/all_types.hpp+8
...@@ -1448,6 +1448,7 @@ enum IrInstructionId {...@@ -1448,6 +1448,7 @@ enum IrInstructionId {
1448 IrInstructionIdToPtrType,1448 IrInstructionIdToPtrType,
1449 IrInstructionIdPtrTypeChild,1449 IrInstructionIdPtrTypeChild,
1450 IrInstructionIdSetFnTest,1450 IrInstructionIdSetFnTest,
1451 IrInstructionIdSetFnVisible,
1451 IrInstructionIdSetDebugSafety,1452 IrInstructionIdSetDebugSafety,
1452 IrInstructionIdArrayType,1453 IrInstructionIdArrayType,
1453 IrInstructionIdSliceType,1454 IrInstructionIdSliceType,
...@@ -1712,6 +1713,13 @@ struct IrInstructionSetFnTest {...@@ -1712,6 +1713,13 @@ struct IrInstructionSetFnTest {
1712 IrInstruction *is_test;1713 IrInstruction *is_test;
1713};1714};
17141715
1716struct IrInstructionSetFnVisible {
1717 IrInstruction base;
1718
1719 IrInstruction *fn_value;
1720 IrInstruction *is_visible;
1721};
1722
1715struct IrInstructionSetDebugSafety {1723struct IrInstructionSetDebugSafety {
1716 IrInstruction base;1724 IrInstruction base;
17171725
src/codegen.cpp+1
...@@ -1649,6 +1649,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1649,6 +1649,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1649 case IrInstructionIdPtrTypeChild:1649 case IrInstructionIdPtrTypeChild:
1650 case IrInstructionIdFieldPtr:1650 case IrInstructionIdFieldPtr:
1651 case IrInstructionIdSetFnTest:1651 case IrInstructionIdSetFnTest:
1652 case IrInstructionIdSetFnVisible:
1652 case IrInstructionIdSetDebugSafety:1653 case IrInstructionIdSetDebugSafety:
1653 case IrInstructionIdArrayType:1654 case IrInstructionIdArrayType:
1654 case IrInstructionIdSliceType:1655 case IrInstructionIdSliceType:
src/ir.cpp+71-42
...@@ -202,6 +202,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) {...@@ -202,6 +202,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) {
202 return IrInstructionIdSetFnTest;202 return IrInstructionIdSetFnTest;
203}203}
204204
205static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnVisible *) {
206 return IrInstructionIdSetFnVisible;
207}
208
205static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {209static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {
206 return IrInstructionIdSetDebugSafety;210 return IrInstructionIdSetDebugSafety;
207}211}
...@@ -808,6 +812,19 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node,...@@ -808,6 +812,19 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node,
808 return &instruction->base;812 return &instruction->base;
809}813}
810814
815static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, AstNode *source_node, IrInstruction *fn_value,
816 IrInstruction *is_visible)
817{
818 IrInstructionSetFnVisible *instruction = ir_build_instruction<IrInstructionSetFnVisible>(irb, source_node);
819 instruction->fn_value = fn_value;
820 instruction->is_visible = is_visible;
821
822 ir_ref_instruction(fn_value);
823 ir_ref_instruction(is_visible);
824
825 return &instruction->base;
826}
827
811static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, AstNode *source_node,828static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, AstNode *source_node,
812 IrInstruction *scope_value, IrInstruction *debug_safety_on)829 IrInstruction *scope_value, IrInstruction *debug_safety_on)
813{830{
...@@ -1432,6 +1449,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1432,6 +1449,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
14321449
1433 return ir_build_set_fn_test(irb, node, arg0_value, arg1_value);1450 return ir_build_set_fn_test(irb, node, arg0_value, arg1_value);
1434 }1451 }
1452 case BuiltinFnIdSetFnVisible:
1453 {
1454 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1455 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
1456 if (arg0_value == irb->codegen->invalid_instruction)
1457 return arg0_value;
1458
1459 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
1460 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->block_context);
1461 if (arg1_value == irb->codegen->invalid_instruction)
1462 return arg1_value;
1463
1464 return ir_build_set_fn_visible(irb, node, arg0_value, arg1_value);
1465 }
1435 case BuiltinFnIdSetDebugSafety:1466 case BuiltinFnIdSetDebugSafety:
1436 {1467 {
1437 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1468 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -1509,7 +1540,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1509,7 +1540,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1509 case BuiltinFnIdDivExact:1540 case BuiltinFnIdDivExact:
1510 case BuiltinFnIdTruncate:1541 case BuiltinFnIdTruncate:
1511 case BuiltinFnIdIntType:1542 case BuiltinFnIdIntType:
1512 case BuiltinFnIdSetFnVisible:
1513 case BuiltinFnIdSetFnStaticEval:1543 case BuiltinFnIdSetFnStaticEval:
1514 case BuiltinFnIdSetFnNoInline:1544 case BuiltinFnIdSetFnNoInline:
1515 zig_panic("TODO IR gen more builtin functions");1545 zig_panic("TODO IR gen more builtin functions");
...@@ -4394,6 +4424,43 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira,...@@ -4394,6 +4424,43 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira,
4394 return ira->codegen->builtin_types.entry_void;4424 return ira->codegen->builtin_types.entry_void;
4395}4425}
43964426
4427static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
4428 IrInstructionSetFnVisible *set_fn_visible_instruction)
4429{
4430 IrInstruction *fn_value = set_fn_visible_instruction->fn_value->other;
4431 IrInstruction *is_visible_value = set_fn_visible_instruction->is_visible->other;
4432
4433 FnTableEntry *fn_entry = ir_resolve_fn(ira, fn_value);
4434 if (!fn_entry)
4435 return ira->codegen->builtin_types.entry_invalid;
4436
4437 bool want_export;
4438 if (!ir_resolve_bool(ira, is_visible_value, &want_export))
4439 return ira->codegen->builtin_types.entry_invalid;
4440
4441 AstNode *source_node = set_fn_visible_instruction->base.source_node;
4442 if (fn_entry->fn_export_set_node) {
4443 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
4444 buf_sprintf("function visibility set twice"));
4445 add_error_note(ira->codegen, msg, fn_entry->fn_export_set_node, buf_sprintf("first set here"));
4446 return ira->codegen->builtin_types.entry_invalid;
4447 }
4448 fn_entry->fn_export_set_node = source_node;
4449
4450 AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;
4451 if (fn_proto->top_level_decl.visib_mod != VisibModExport) {
4452 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
4453 buf_sprintf("function must be marked export to set function visibility"));
4454 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("function declared here"));
4455 return ira->codegen->builtin_types.entry_invalid;
4456 }
4457 if (!want_export)
4458 LLVMSetLinkage(fn_entry->fn_value, LLVMInternalLinkage);
4459
4460 ir_build_const_from(ira, &set_fn_visible_instruction->base, false);
4461 return ira->codegen->builtin_types.entry_void;
4462}
4463
4397static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,4464static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
4398 IrInstructionSetDebugSafety *set_debug_safety_instruction)4465 IrInstructionSetDebugSafety *set_debug_safety_instruction)
4399{4466{
...@@ -4847,6 +4914,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -4847,6 +4914,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
4847 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);4914 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
4848 case IrInstructionIdSetFnTest:4915 case IrInstructionIdSetFnTest:
4849 return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction);4916 return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction);
4917 case IrInstructionIdSetFnVisible:
4918 return ir_analyze_instruction_set_fn_visible(ira, (IrInstructionSetFnVisible *)instruction);
4850 case IrInstructionIdSetDebugSafety:4919 case IrInstructionIdSetDebugSafety:
4851 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);4920 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
4852 case IrInstructionIdSliceType:4921 case IrInstructionIdSliceType:
...@@ -4957,6 +5026,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -4957,6 +5026,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
4957 case IrInstructionIdReturn:5026 case IrInstructionIdReturn:
4958 case IrInstructionIdUnreachable:5027 case IrInstructionIdUnreachable:
4959 case IrInstructionIdSetFnTest:5028 case IrInstructionIdSetFnTest:
5029 case IrInstructionIdSetFnVisible:
4960 case IrInstructionIdSetDebugSafety:5030 case IrInstructionIdSetDebugSafety:
4961 return true;5031 return true;
4962 case IrInstructionIdPhi:5032 case IrInstructionIdPhi:
...@@ -5523,44 +5593,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -5523,44 +5593,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
5523// return g->builtin_types.entry_void;5593// return g->builtin_types.entry_void;
5524//}5594//}
5525//5595//
5526//static TypeTableEntry *analyze_set_fn_visible(CodeGen *g, ImportTableEntry *import,
5527// BlockContext *context, AstNode *node)
5528//{
5529// AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
5530// AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5531//
5532// FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
5533// if (!fn_entry) {
5534// return g->builtin_types.entry_invalid;
5535// }
5536//
5537// bool want_export;
5538// bool ok = resolve_const_expr_bool(g, import, context, value_node, &want_export);
5539// if (!ok) {
5540// return g->builtin_types.entry_invalid;
5541// }
5542//
5543// if (fn_entry->fn_export_set_node) {
5544// ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function visibility set twice"));
5545// add_error_note(g, msg, fn_entry->fn_export_set_node, buf_sprintf("first set here"));
5546// return g->builtin_types.entry_invalid;
5547// }
5548// fn_entry->fn_export_set_node = node;
5549//
5550// AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;
5551// if (fn_proto->top_level_decl.visib_mod != VisibModExport) {
5552// ErrorMsg *msg = add_node_error(g, node,
5553// buf_sprintf("function must be marked export to set function visibility"));
5554// add_error_note(g, msg, fn_entry->proto_node, buf_sprintf("function declared here"));
5555// return g->builtin_types.entry_void;
5556// }
5557// if (!want_export) {
5558// fn_proto->top_level_decl.visib_mod = VisibModPub;
5559// }
5560//
5561// return g->builtin_types.entry_void;
5562//}
5563//
5564//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,5596//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
5565// TypeTableEntry *expected_type, AstNode *node)5597// TypeTableEntry *expected_type, AstNode *node)
5566//{5598//{
...@@ -5784,8 +5816,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -5784,8 +5816,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
5784// return analyze_set_fn_no_inline(g, import, context, node);5816// return analyze_set_fn_no_inline(g, import, context, node);
5785// case BuiltinFnIdSetFnStaticEval:5817// case BuiltinFnIdSetFnStaticEval:
5786// return analyze_set_fn_static_eval(g, import, context, node);5818// return analyze_set_fn_static_eval(g, import, context, node);
5787// case BuiltinFnIdSetFnVisible:
5788// return analyze_set_fn_visible(g, import, context, node);
5789// }5819// }
5790// zig_unreachable();5820// zig_unreachable();
5791//}5821//}
...@@ -8310,7 +8340,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no...@@ -8310,7 +8340,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no
8310// case BuiltinFnIdUnreachable:8340// case BuiltinFnIdUnreachable:
8311// zig_panic("moved to ir render");8341// zig_panic("moved to ir render");
8312// case BuiltinFnIdSetFnTest:8342// case BuiltinFnIdSetFnTest:
8313// case BuiltinFnIdSetFnVisible:
8314// case BuiltinFnIdSetFnStaticEval:8343// case BuiltinFnIdSetFnStaticEval:
8315// case BuiltinFnIdSetFnNoInline:8344// case BuiltinFnIdSetFnNoInline:
8316// case BuiltinFnIdSetDebugSafety:8345// case BuiltinFnIdSetDebugSafety:
src/ir_print.cpp+11
...@@ -425,6 +425,14 @@ static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instructi...@@ -425,6 +425,14 @@ static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instructi
425 fprintf(irp->f, ")");425 fprintf(irp->f, ")");
426}426}
427427
428static void ir_print_set_fn_visible(IrPrint *irp, IrInstructionSetFnVisible *instruction) {
429 fprintf(irp->f, "@setFnVisible(");
430 ir_print_other_instruction(irp, instruction->fn_value);
431 fprintf(irp->f, ", ");
432 ir_print_other_instruction(irp, instruction->is_visible);
433 fprintf(irp->f, ")");
434}
435
428static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {436static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {
429 fprintf(irp->f, "@setDebugSafety(");437 fprintf(irp->f, "@setDebugSafety(");
430 ir_print_other_instruction(irp, instruction->scope_value);438 ir_print_other_instruction(irp, instruction->scope_value);
...@@ -603,6 +611,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -603,6 +611,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
603 case IrInstructionIdSetFnTest:611 case IrInstructionIdSetFnTest:
604 ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);612 ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);
605 break;613 break;
614 case IrInstructionIdSetFnVisible:
615 ir_print_set_fn_visible(irp, (IrInstructionSetFnVisible *)instruction);
616 break;
606 case IrInstructionIdSetDebugSafety:617 case IrInstructionIdSetDebugSafety:
607 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);618 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);
608 break;619 break;
std/compiler_rt.zig+263-262
...@@ -1,262 +1,263 @@...@@ -1,262 +1,263 @@
1const CHAR_BIT = 8;1// TODO
2const du_int = u64;2//const CHAR_BIT = 8;
3const di_int = i64;3//const du_int = u64;
4const si_int = c_int;4//const di_int = i64;
5const su_int = c_uint;5//const si_int = c_int;
66//const su_int = c_uint;
7const udwords = [2]su_int;7//
8const low = if (@compileVar("is_big_endian")) 1 else 0;8//const udwords = [2]su_int;
9const high = 1 - low;9//const low = if (@compileVar("is_big_endian")) 1 else 0;
1010//const high = 1 - low;
11export fn __udivdi3(a: du_int, b: du_int) -> du_int {11//
12 @setDebugSafety(this, false);12//export fn __udivdi3(a: du_int, b: du_int) -> du_int {
13 return __udivmoddi4(a, b, null);13// @setDebugSafety(this, false);
14}14// return __udivmoddi4(a, b, null);
1515//}
16fn du_int_to_udwords(x: du_int) -> udwords {16//
17 @setDebugSafety(this, false);17//fn du_int_to_udwords(x: du_int) -> udwords {
18 return *(&udwords)(&x);18// @setDebugSafety(this, false);
19}19// return *(&udwords)(&x);
2020//}
21export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {21//
22 @setDebugSafety(this, false);22//export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
2323// @setDebugSafety(this, false);
24 const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;24//
25 const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;25// const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;
26 var n = du_int_to_udwords(a);26// const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;
27 var d = du_int_to_udwords(b);27// var n = du_int_to_udwords(a);
28 var q: udwords = undefined;28// var d = du_int_to_udwords(b);
29 var r: udwords = undefined;29// var q: udwords = undefined;
30 var sr: c_uint = undefined;30// var r: udwords = undefined;
31 // special cases, X is unknown, K != 031// var sr: c_uint = undefined;
32 if (n[high] == 0) {32// // special cases, X is unknown, K != 0
33 if (d[high] == 0) {33// if (n[high] == 0) {
34 // 0 X34// if (d[high] == 0) {
35 // ---35// // 0 X
36 // 0 X36// // ---
37 if (const rem ?= maybe_rem) {37// // 0 X
38 *rem = n[low] % d[low];38// if (const rem ?= maybe_rem) {
39 }39// *rem = n[low] % d[low];
40 return n[low] / d[low];40// }
41 }41// return n[low] / d[low];
42 // 0 X42// }
43 // ---43// // 0 X
44 // K X44// // ---
45 if (const rem ?= maybe_rem) {45// // K X
46 *rem = n[low];46// if (const rem ?= maybe_rem) {
47 }47// *rem = n[low];
48 return 0;48// }
49 }49// return 0;
50 // n[high] != 050// }
51 if (d[low] == 0) {51// // n[high] != 0
52 if (d[high] == 0) {52// if (d[low] == 0) {
53 // K X53// if (d[high] == 0) {
54 // ---54// // K X
55 // 0 055// // ---
56 if (var rem ?= maybe_rem) {56// // 0 0
57 *rem = n[high] % d[low];57// if (var rem ?= maybe_rem) {
58 }58// *rem = n[high] % d[low];
59 return n[high] / d[low];59// }
60 }60// return n[high] / d[low];
61 // d[high] != 061// }
62 if (n[low] == 0) {62// // d[high] != 0
63 // K 063// if (n[low] == 0) {
64 // ---64// // K 0
65 // K 065// // ---
66 if (var rem ?= maybe_rem) {66// // K 0
67 r[high] = n[high] % d[high];67// if (var rem ?= maybe_rem) {
68 r[low] = 0;68// r[high] = n[high] % d[high];
69 *rem = *(&du_int)(&r[0]);69// r[low] = 0;
70 }70// *rem = *(&du_int)(&r[0]);
71 return n[high] / d[high];71// }
72 }72// return n[high] / d[high];
73 // K K73// }
74 // ---74// // K K
75 // K 075// // ---
76 // if d is a power of 276// // K 0
77 if ((d[high] & (d[high] - 1)) == 0) {77// // if d is a power of 2
78 if (var rem ?= maybe_rem) {78// if ((d[high] & (d[high] - 1)) == 0) {
79 r[low] = n[low];79// if (var rem ?= maybe_rem) {
80 r[high] = n[high] & (d[high] - 1);80// r[low] = n[low];
81 *rem = *(&du_int)(&r[0]);81// r[high] = n[high] & (d[high] - 1);
82 }82// *rem = *(&du_int)(&r[0]);
83 return n[high] >> @ctz(@typeOf(d[high]), d[high]);83// }
84 }84// return n[high] >> @ctz(@typeOf(d[high]), d[high]);
85 // K K85// }
86 // ---86// // K K
87 // K 087// // ---
88 sr = @clz(su_int, d[high]) - @clz(su_int, n[high]);88// // K 0
89 // 0 <= sr <= n_uword_bits - 2 or sr large89// sr = @clz(su_int, d[high]) - @clz(su_int, n[high]);
90 if (sr > n_uword_bits - 2) {90// // 0 <= sr <= n_uword_bits - 2 or sr large
91 if (var rem ?= maybe_rem) {91// if (sr > n_uword_bits - 2) {
92 *rem = *(&du_int)(&n[0]);92// if (var rem ?= maybe_rem) {
93 }93// *rem = *(&du_int)(&n[0]);
94 return 0;94// }
95 }95// return 0;
96 sr += 1;96// }
97 // 1 <= sr <= n_uword_bits - 197// sr += 1;
98 // q.all = n.all << (n_udword_bits - sr);98// // 1 <= sr <= n_uword_bits - 1
99 q[low] = 0;99// // q.all = n.all << (n_udword_bits - sr);
100 q[high] = n[low] << (n_uword_bits - sr);100// q[low] = 0;
101 // r.all = n.all >> sr;101// q[high] = n[low] << (n_uword_bits - sr);
102 r[high] = n[high] >> sr;102// // r.all = n.all >> sr;
103 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);103// r[high] = n[high] >> sr;
104 } else {104// r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
105 // d[low] != 0105// } else {
106 if (d[high] == 0) {106// // d[low] != 0
107 // K X107// if (d[high] == 0) {
108 // ---108// // K X
109 // 0 K109// // ---
110 // if d is a power of 2110// // 0 K
111 if ((d[low] & (d[low] - 1)) == 0) {111// // if d is a power of 2
112 if (var rem ?= maybe_rem) {112// if ((d[low] & (d[low] - 1)) == 0) {
113 *rem = n[low] & (d[low] - 1);113// if (var rem ?= maybe_rem) {
114 }114// *rem = n[low] & (d[low] - 1);
115 if (d[low] == 1) {115// }
116 return *(&du_int)(&n[0]);116// if (d[low] == 1) {
117 }117// return *(&du_int)(&n[0]);
118 sr = @ctz(@typeOf(d[low]), d[low]);118// }
119 q[high] = n[high] >> sr;119// sr = @ctz(@typeOf(d[low]), d[low]);
120 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);120// q[high] = n[high] >> sr;
121 return *(&du_int)(&q[0]);121// q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
122 }122// return *(&du_int)(&q[0]);
123 // K X123// }
124 // ---124// // K X
125 // 0 K125// // ---
126 sr = 1 + n_uword_bits + @clz(su_int, d[low]) - @clz(su_int, n[high]);126// // 0 K
127 // 2 <= sr <= n_udword_bits - 1127// sr = 1 + n_uword_bits + @clz(su_int, d[low]) - @clz(su_int, n[high]);
128 // q.all = n.all << (n_udword_bits - sr);128// // 2 <= sr <= n_udword_bits - 1
129 // r.all = n.all >> sr;129// // q.all = n.all << (n_udword_bits - sr);
130 if (sr == n_uword_bits) {130// // r.all = n.all >> sr;
131 q[low] = 0;131// if (sr == n_uword_bits) {
132 q[high] = n[low];132// q[low] = 0;
133 r[high] = 0;133// q[high] = n[low];
134 r[low] = n[high];134// r[high] = 0;
135 } else if (sr < n_uword_bits) {135// r[low] = n[high];
136 // 2 <= sr <= n_uword_bits - 1136// } else if (sr < n_uword_bits) {
137 q[low] = 0;137// // 2 <= sr <= n_uword_bits - 1
138 q[high] = n[low] << (n_uword_bits - sr);138// q[low] = 0;
139 r[high] = n[high] >> sr;139// q[high] = n[low] << (n_uword_bits - sr);
140 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);140// r[high] = n[high] >> sr;
141 } else {141// r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
142 // n_uword_bits + 1 <= sr <= n_udword_bits - 1142// } else {
143 q[low] = n[low] << (n_udword_bits - sr);143// // n_uword_bits + 1 <= sr <= n_udword_bits - 1
144 q[high] = (n[high] << (n_udword_bits - sr)) |144// q[low] = n[low] << (n_udword_bits - sr);
145 (n[low] >> (sr - n_uword_bits));145// q[high] = (n[high] << (n_udword_bits - sr)) |
146 r[high] = 0;146// (n[low] >> (sr - n_uword_bits));
147 r[low] = n[high] >> (sr - n_uword_bits);147// r[high] = 0;
148 }148// r[low] = n[high] >> (sr - n_uword_bits);
149 } else {149// }
150 // K X150// } else {
151 // ---151// // K X
152 // K K152// // ---
153 sr = @clz(su_int, d[high]) - @clz(su_int, n[high]);153// // K K
154 // 0 <= sr <= n_uword_bits - 1 or sr large154// sr = @clz(su_int, d[high]) - @clz(su_int, n[high]);
155 if (sr > n_uword_bits - 1) {155// // 0 <= sr <= n_uword_bits - 1 or sr large
156 if (var rem ?= maybe_rem) {156// if (sr > n_uword_bits - 1) {
157 *rem = *(&du_int)(&n[0]);157// if (var rem ?= maybe_rem) {
158 }158// *rem = *(&du_int)(&n[0]);
159 return 0;159// }
160 }160// return 0;
161 sr += 1;161// }
162 // 1 <= sr <= n_uword_bits162// sr += 1;
163 // q.all = n.all << (n_udword_bits - sr);163// // 1 <= sr <= n_uword_bits
164 q[low] = 0;164// // q.all = n.all << (n_udword_bits - sr);
165 if (sr == n_uword_bits) {165// q[low] = 0;
166 q[high] = n[low];166// if (sr == n_uword_bits) {
167 r[high] = 0;167// q[high] = n[low];
168 r[low] = n[high];168// r[high] = 0;
169 } else {169// r[low] = n[high];
170 q[high] = n[low] << (n_uword_bits - sr);170// } else {
171 r[high] = n[high] >> sr;171// q[high] = n[low] << (n_uword_bits - sr);
172 r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);172// r[high] = n[high] >> sr;
173 }173// r[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
174 }174// }
175 }175// }
176 // Not a special case176// }
177 // q and r are initialized with:177// // Not a special case
178 // q.all = n.all << (n_udword_bits - sr);178// // q and r are initialized with:
179 // r.all = n.all >> sr;179// // q.all = n.all << (n_udword_bits - sr);
180 // 1 <= sr <= n_udword_bits - 1180// // r.all = n.all >> sr;
181 var carry: su_int = 0;181// // 1 <= sr <= n_udword_bits - 1
182 while (sr > 0) {182// var carry: su_int = 0;
183 // r:q = ((r:q) << 1) | carry183// while (sr > 0) {
184 r[high] = (r[high] << 1) | (r[low] >> (n_uword_bits - 1));184// // r:q = ((r:q) << 1) | carry
185 r[low] = (r[low] << 1) | (q[high] >> (n_uword_bits - 1));185// r[high] = (r[high] << 1) | (r[low] >> (n_uword_bits - 1));
186 q[high] = (q[high] << 1) | (q[low] >> (n_uword_bits - 1));186// r[low] = (r[low] << 1) | (q[high] >> (n_uword_bits - 1));
187 q[low] = (q[low] << 1) | carry;187// q[high] = (q[high] << 1) | (q[low] >> (n_uword_bits - 1));
188 // carry = 0;188// q[low] = (q[low] << 1) | carry;
189 // if (r.all >= d.all)189// // carry = 0;
190 // {190// // if (r.all >= d.all)
191 // r.all -= d.all;191// // {
192 // carry = 1;192// // r.all -= d.all;
193 // }193// // carry = 1;
194 const s: di_int = (di_int)(*(&du_int)(&d[0]) - *(&du_int)(&r[0]) - 1) >> (n_udword_bits - 1);194// // }
195 carry = su_int(s & 1);195// const s: di_int = (di_int)(*(&du_int)(&d[0]) - *(&du_int)(&r[0]) - 1) >> (n_udword_bits - 1);
196 *(&du_int)(&r[0]) -= *(&du_int)(&d[0]) & u64(s);196// carry = su_int(s & 1);
197197// *(&du_int)(&r[0]) -= *(&du_int)(&d[0]) & u64(s);
198 sr -= 1;198//
199 }199// sr -= 1;
200 *(&du_int)(&q[0]) = (*(&du_int)(&q[0]) << 1) | u64(carry);200// }
201 if (var rem ?= maybe_rem) {201// *(&du_int)(&q[0]) = (*(&du_int)(&q[0]) << 1) | u64(carry);
202 *rem = *(&du_int)(&r[0]);202// if (var rem ?= maybe_rem) {
203 }203// *rem = *(&du_int)(&r[0]);
204 return *(&du_int)(&q[0]);204// }
205}205// return *(&du_int)(&q[0]);
206206//}
207export fn __umoddi3(a: du_int, b: du_int) -> du_int {207//
208 @setDebugSafety(this, false);208//export fn __umoddi3(a: du_int, b: du_int) -> du_int {
209209// @setDebugSafety(this, false);
210 var r: du_int = undefined;210//
211 __udivmoddi4(a, b, &r);211// var r: du_int = undefined;
212 return r;212// __udivmoddi4(a, b, &r);
213}213// return r;
214214//}
215fn test_umoddi3() {215//
216 @setFnTest(this, true);216//fn test_umoddi3() {
217217// @setFnTest(this, true);
218 test_one_umoddi3(0, 1, 0);218//
219 test_one_umoddi3(2, 1, 0);219// test_one_umoddi3(0, 1, 0);
220 test_one_umoddi3(0x8000000000000000, 1, 0x0);220// test_one_umoddi3(2, 1, 0);
221 test_one_umoddi3(0x8000000000000000, 2, 0x0);221// test_one_umoddi3(0x8000000000000000, 1, 0x0);
222 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);222// test_one_umoddi3(0x8000000000000000, 2, 0x0);
223}223// test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
224224//}
225fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {225//
226 const r = __umoddi3(a, b);226//fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {
227 assert(r == expected_r);227// const r = __umoddi3(a, b);
228}228// assert(r == expected_r);
229229//}
230fn test_udivmoddi4() {230//
231 @setFnTest(this, true);231//fn test_udivmoddi4() {
232232// @setFnTest(this, true);
233 const cases = [][4]du_int {233//
234 []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},234// const cases = [][4]du_int {
235 []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000},235// []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
236 []du_int{0x7FFFFFFF00000001, 0x0000000000000001, 0x7FFFFFFF00000001, 0x0000000000000000},236// []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000},
237 []du_int{0x7FFFFFFF7FFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x7FFFFFFF7FFFFFFF},237// []du_int{0x7FFFFFFF00000001, 0x0000000000000001, 0x7FFFFFFF00000001, 0x0000000000000000},
238 []du_int{0x8000000000000002, 0xFFFFFFFFFFFFFFFE, 0x0000000000000000, 0x8000000000000002},238// []du_int{0x7FFFFFFF7FFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x7FFFFFFF7FFFFFFF},
239 []du_int{0x80000000FFFFFFFD, 0xFFFFFFFFFFFFFFFD, 0x0000000000000000, 0x80000000FFFFFFFD},239// []du_int{0x8000000000000002, 0xFFFFFFFFFFFFFFFE, 0x0000000000000000, 0x8000000000000002},
240 []du_int{0xFFFFFFFD00000010, 0xFFFFFFFF80000000, 0x0000000000000000, 0xFFFFFFFD00000010},240// []du_int{0x80000000FFFFFFFD, 0xFFFFFFFFFFFFFFFD, 0x0000000000000000, 0x80000000FFFFFFFD},
241 []du_int{0xFFFFFFFDFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0x0000000000000000, 0xFFFFFFFDFFFFFFFF},241// []du_int{0xFFFFFFFD00000010, 0xFFFFFFFF80000000, 0x0000000000000000, 0xFFFFFFFD00000010},
242 []du_int{0xFFFFFFFE0747AE14, 0xFFFFFFFF0747AE14, 0x0000000000000000, 0xFFFFFFFE0747AE14},242// []du_int{0xFFFFFFFDFFFFFFFF, 0xFFFFFFFF7FFFFFFF, 0x0000000000000000, 0xFFFFFFFDFFFFFFFF},
243 []du_int{0xFFFFFFFF00000001, 0xFFFFFFFF078644FA, 0x0000000000000000, 0xFFFFFFFF00000001},243// []du_int{0xFFFFFFFE0747AE14, 0xFFFFFFFF0747AE14, 0x0000000000000000, 0xFFFFFFFE0747AE14},
244 []du_int{0xFFFFFFFF80000000, 0xFFFFFFFF00000010, 0x0000000000000001, 0x000000007FFFFFF0},244// []du_int{0xFFFFFFFF00000001, 0xFFFFFFFF078644FA, 0x0000000000000000, 0xFFFFFFFF00000001},
245 []du_int{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000001, 0x0000000000000000},245// []du_int{0xFFFFFFFF80000000, 0xFFFFFFFF00000010, 0x0000000000000001, 0x000000007FFFFFF0},
246 };246// []du_int{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000001, 0x0000000000000000},
247247// };
248 for (cases) |case| {248//
249 test_one_udivmoddi4(case[0], case[1], case[2], case[3]);249// for (cases) |case| {
250 }250// test_one_udivmoddi4(case[0], case[1], case[2], case[3]);
251}251// }
252252//}
253fn test_one_udivmoddi4(a: du_int, b: du_int, expected_q: du_int, expected_r: du_int) {253//
254 var r: du_int = undefined;254//fn test_one_udivmoddi4(a: du_int, b: du_int, expected_q: du_int, expected_r: du_int) {
255 const q = __udivmoddi4(a, b, &r);255// var r: du_int = undefined;
256 assert(q == expected_q);256// const q = __udivmoddi4(a, b, &r);
257 assert(r == expected_r);257// assert(q == expected_q);
258}258// assert(r == expected_r);
259259//}
260fn assert(b: bool) {260//
261 if (!b) @unreachable();261//fn assert(b: bool) {
262}262// if (!b) @unreachable();
263//}
test/self_hosted2.zig+17-1
...@@ -1,13 +1,29 @@...@@ -1,13 +1,29 @@
1pub const SYS_write = 1;1pub const SYS_write = 1;
2pub const SYS_exit = 60;2pub const SYS_exit = 60;
3pub const stdout_fileno = 1;3pub const stdout_fileno = 1;
4const text = "hello\n";4
5// normal comment
6/// this is a documentation comment
7/// doc comment line 2
8fn emptyFunctionWithComments() {
9}
10
11export fn disabledExternFn() {
12 @setFnVisible(this, false);
13}
14
15fn runAllTests() {
16 emptyFunctionWithComments();
17 disabledExternFn();
18}
519
6export nakedcc fn _start() -> unreachable {20export nakedcc fn _start() -> unreachable {
7 myMain();21 myMain();
8}22}
923
10fn myMain() -> unreachable {24fn myMain() -> unreachable {
25 runAllTests();
26 const text = "OK\n";
11 write(stdout_fileno, &text[0], text.len);27 write(stdout_fileno, &text[0], text.len);
12 exit(0);28 exit(0);
13}29}