authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-11 16:30:01-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-11 16:30:01-05:00
log9b17c0ff7fa7a3981697f4239afb5c66c609cd42
tree96c2ae36609632900b8342387b181cecec31a6e1
parent3429639e848a9ffa9ff9fbd940d3fc2d348e10e7

IR: implement intType builtin

and int type field access and fix compile time bool not

7 files changed, 220 insertions(+), 120 deletions(-)

src/all_types.hpp+15-1
......@@ -1411,6 +1411,8 @@ enum IrInstructionId {
14111411 IrInstructionIdFence,
14121412 IrInstructionIdDivExact,
14131413 IrInstructionIdTruncate,
1414 IrInstructionIdIntType,
1415 IrInstructionIdBoolNot,
14141416};
14151417
14161418struct IrInstruction {
......@@ -1481,7 +1483,6 @@ struct IrInstructionPhi {
14811483
14821484enum IrUnOp {
14831485 IrUnOpInvalid,
1484 IrUnOpBoolNot,
14851486 IrUnOpBinNot,
14861487 IrUnOpNegation,
14871488 IrUnOpNegationWrap,
......@@ -1900,6 +1901,19 @@ struct IrInstructionTruncate {
19001901 IrInstruction *target;
19011902};
19021903
1904struct IrInstructionIntType {
1905 IrInstruction base;
1906
1907 IrInstruction *is_signed;
1908 IrInstruction *bit_count;
1909};
1910
1911struct IrInstructionBoolNot {
1912 IrInstruction base;
1913
1914 IrInstruction *value;
1915};
1916
19031917enum LValPurpose {
19041918 LValPurposeNone,
19051919 LValPurposeAssign,
src/analyze.cpp+11
......@@ -2809,3 +2809,14 @@ ConstExprValue *create_const_enum_tag(uint64_t tag) {
28092809 init_const_enum_tag(const_val, tag);
28102810 return const_val;
28112811}
2812
2813void init_const_bool(ConstExprValue *const_val, bool value) {
2814 const_val->special = ConstValSpecialStatic;
2815 const_val->data.x_bool = value;
2816}
2817
2818ConstExprValue *create_const_bool(bool value) {
2819 ConstExprValue *const_val = allocate<ConstExprValue>(1);
2820 init_const_bool(const_val, value);
2821 return const_val;
2822}
src/analyze.hpp+3
......@@ -98,4 +98,7 @@ ConstExprValue *create_const_float(double value);
9898void init_const_enum_tag(ConstExprValue *const_val, uint64_t tag);
9999ConstExprValue *create_const_enum_tag(uint64_t tag);
100100
101void init_const_bool(ConstExprValue *const_val, bool value);
102ConstExprValue *create_const_bool(bool value);
103
101104#endif
src/codegen.cpp+9-5
......@@ -1230,11 +1230,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
12301230 zig_unreachable();
12311231 }
12321232 }
1233 case IrUnOpBoolNot:
1234 {
1235 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
1236 return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, "");
1237 }
12381233 case IrUnOpBinNot:
12391234 return LLVMBuildNot(g->builder, expr, "");
12401235 case IrUnOpAddressOf:
......@@ -1339,6 +1334,12 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
13391334 zig_unreachable();
13401335}
13411336
1337static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrInstructionBoolNot *instruction) {
1338 LLVMValueRef value = ir_llvm_value(g, instruction->value);
1339 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value));
1340 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
1341}
1342
13421343static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
13431344 IrInstructionDeclVar *decl_var_instruction)
13441345{
......@@ -1927,6 +1928,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
19271928 case IrInstructionIdCDefine:
19281929 case IrInstructionIdCUndef:
19291930 case IrInstructionIdEmbedFile:
1931 case IrInstructionIdIntType:
19301932 zig_unreachable();
19311933 case IrInstructionIdReturn:
19321934 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -1984,6 +1986,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
19841986 return ir_render_div_exact(g, executable, (IrInstructionDivExact *)instruction);
19851987 case IrInstructionIdTruncate:
19861988 return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction);
1989 case IrInstructionIdBoolNot:
1990 return ir_render_bool_not(g, executable, (IrInstructionBoolNot *)instruction);
19871991 case IrInstructionIdSwitchVar:
19881992 case IrInstructionIdContainerInitList:
19891993 case IrInstructionIdStructInit:
src/ir.cpp+133-112
......@@ -363,6 +363,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) {
363363 return IrInstructionIdTruncate;
364364}
365365
366static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
367 return IrInstructionIdIntType;
368}
369
370static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) {
371 return IrInstructionIdBoolNot;
372}
373
366374template<typename T>
367375static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
368376 T *special_instruction = allocate<T>(1);
......@@ -1455,6 +1463,32 @@ static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_
14551463 return new_instruction;
14561464}
14571465
1466static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) {
1467 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node);
1468 instruction->is_signed = is_signed;
1469 instruction->bit_count = bit_count;
1470
1471 ir_ref_instruction(is_signed);
1472 ir_ref_instruction(bit_count);
1473
1474 return &instruction->base;
1475}
1476
1477static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1478 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node);
1479 instruction->value = value;
1480
1481 ir_ref_instruction(value);
1482
1483 return &instruction->base;
1484}
1485
1486static IrInstruction *ir_build_bool_not_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1487 IrInstruction *new_instruction = ir_build_bool_not(irb, old_instruction->scope, old_instruction->source_node, value);
1488 ir_link_new_instruction(new_instruction, old_instruction);
1489 return new_instruction;
1490}
1491
14581492static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
14591493 bool gen_error_defers, bool gen_maybe_defers)
14601494{
......@@ -2262,6 +2296,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
22622296
22632297 return ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
22642298 }
2299 case BuiltinFnIdIntType:
2300 {
2301 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
2302 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
2303 if (arg0_value == irb->codegen->invalid_instruction)
2304 return arg0_value;
2305
2306 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
2307 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
2308 if (arg1_value == irb->codegen->invalid_instruction)
2309 return arg1_value;
2310
2311 return ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
2312 }
22652313 case BuiltinFnIdMemcpy:
22662314 case BuiltinFnIdMemset:
22672315 case BuiltinFnIdAlignof:
......@@ -2273,7 +2321,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
22732321 case BuiltinFnIdBreakpoint:
22742322 case BuiltinFnIdReturnAddress:
22752323 case BuiltinFnIdFrameAddress:
2276 case BuiltinFnIdIntType:
22772324 zig_panic("TODO IR gen more builtin functions");
22782325 }
22792326 zig_unreachable();
......@@ -2379,6 +2426,28 @@ static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, Scope *scope
23792426 return unwrapped_ptr;
23802427}
23812428
2429static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) {
2430 assert(node->type == NodeTypePrefixOpExpr);
2431 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
2432
2433 IrInstruction *value = ir_gen_node(irb, expr_node, scope);
2434 if (value == irb->codegen->invalid_instruction)
2435 return irb->codegen->invalid_instruction;
2436
2437 return ir_build_bool_not(irb, scope, node, value);
2438}
2439
2440static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LValPurpose lval) {
2441 if (lval == LValPurposeNone)
2442 return value;
2443 if (value == irb->codegen->invalid_instruction)
2444 return value;
2445
2446 // We needed a pointer to a value, but we got a value. So we create
2447 // an instruction which just makes a const pointer of it.
2448 return ir_build_ref(irb, scope, value->source_node, value);
2449}
2450
23822451static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
23832452 assert(node->type == NodeTypePrefixOpExpr);
23842453
......@@ -2388,7 +2457,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
23882457 case PrefixOpInvalid:
23892458 zig_unreachable();
23902459 case PrefixOpBoolNot:
2391 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBoolNot);
2460 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval);
23922461 case PrefixOpBinNot:
23932462 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot);
23942463 case PrefixOpNegation:
......@@ -3124,17 +3193,6 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod
31243193 return ir_build_br(irb, scope, node, dest_block, is_inline);
31253194}
31263195
3127static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LValPurpose lval) {
3128 if (lval == LValPurposeNone)
3129 return value;
3130 if (value == irb->codegen->invalid_instruction)
3131 return value;
3132
3133 // We needed a pointer to a value, but we got a value. So we create
3134 // an instruction which just makes a const pointer of it.
3135 return ir_build_ref(irb, scope, value->source_node, value);
3136}
3137
31383196static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
31393197 assert(node->type == NodeTypeTypeLiteral);
31403198 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type);
......@@ -5136,31 +5194,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
51365194 }
51375195}
51385196
5139static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
5140 IrInstruction *value = un_op_instruction->value->other;
5141 if (value->type_entry->id == TypeTableEntryIdInvalid)
5142 return ira->codegen->builtin_types.entry_invalid;
5143
5144 TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool;
5145
5146 IrInstruction *casted_value = ir_get_casted_value(ira, value, bool_type);
5147 if (casted_value->type_entry->id == TypeTableEntryIdInvalid)
5148 return ira->codegen->builtin_types.entry_invalid;
5149
5150 ConstExprValue *operand_val = &casted_value->static_value;
5151 if (operand_val->special != ConstValSpecialRuntime) {
5152 ConstExprValue *result_val = &un_op_instruction->base.static_value;
5153 result_val->special = ConstValSpecialStatic;
5154 result_val->depends_on_compile_var = operand_val->depends_on_compile_var;
5155 result_val->data.x_bool = !operand_val->data.x_bool;
5156 return bool_type;
5157 }
5158
5159 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, IrUnOpBoolNot, casted_value);
5160
5161 return bool_type;
5162}
5163
51645197static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
51655198 assert(un_op_instruction->op_id == IrUnOpError);
51665199 IrInstruction *value = un_op_instruction->value->other;
......@@ -5425,8 +5458,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio
54255458 switch (op_id) {
54265459 case IrUnOpInvalid:
54275460 zig_unreachable();
5428 case IrUnOpBoolNot:
5429 return ir_analyze_unary_bool_not(ira, un_op_instruction);
54305461 case IrUnOpBinNot:
54315462 zig_panic("TODO analyze PrefixOpBinNot");
54325463 //{
......@@ -5961,9 +5992,22 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
59615992 buf_sprintf("use of undeclared error value '%s'", buf_ptr(field_name)));
59625993 return ira->codegen->builtin_types.entry_invalid;
59635994 } else if (child_type->id == TypeTableEntryIdInt) {
5964 zig_panic("TODO integer type field");
5995 if (buf_eql_str(field_name, "bit_count")) {
5996 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
5997 create_const_unsigned_negative(child_type->data.integral.bit_count, false),
5998 ira->codegen->builtin_types.entry_num_lit_int, depends_on_compile_var, ConstPtrSpecialNone);
5999 } else if (buf_eql_str(field_name, "is_signed")) {
6000 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
6001 create_const_bool(child_type->data.integral.is_signed),
6002 ira->codegen->builtin_types.entry_bool, depends_on_compile_var, ConstPtrSpecialNone);
6003 } else {
6004 ir_add_error(ira, &field_ptr_instruction->base,
6005 buf_sprintf("type '%s' has no member called '%s'",
6006 buf_ptr(&child_type->name), buf_ptr(field_name)));
6007 return ira->codegen->builtin_types.entry_invalid;
6008 }
59656009 } else {
5966 add_node_error(ira->codegen, source_node,
6010 ir_add_error(ira, &field_ptr_instruction->base,
59676011 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
59686012 return ira->codegen->builtin_types.entry_invalid;
59696013 }
......@@ -7620,6 +7664,47 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc
76207664 return dest_type;
76217665}
76227666
7667static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
7668 IrInstruction *is_signed_value = instruction->is_signed->other;
7669 bool is_signed;
7670 if (!ir_resolve_bool(ira, is_signed_value, &is_signed))
7671 return ira->codegen->builtin_types.entry_invalid;
7672
7673 IrInstruction *bit_count_value = instruction->bit_count->other;
7674 uint64_t bit_count;
7675 if (!ir_resolve_usize(ira, bit_count_value, &bit_count))
7676 return ira->codegen->builtin_types.entry_invalid;
7677
7678 bool depends_on_compile_var = is_signed_value->static_value.depends_on_compile_var ||
7679 bit_count_value->static_value.depends_on_compile_var;
7680
7681 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var);
7682 out_val->data.x_type = get_int_type(ira->codegen, is_signed, bit_count);
7683 return ira->codegen->builtin_types.entry_type;
7684}
7685
7686static TypeTableEntry *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) {
7687 IrInstruction *value = instruction->value->other;
7688 if (value->type_entry->id == TypeTableEntryIdInvalid)
7689 return ira->codegen->builtin_types.entry_invalid;
7690
7691 TypeTableEntry *bool_type = ira->codegen->builtin_types.entry_bool;
7692
7693 IrInstruction *casted_value = ir_get_casted_value(ira, value, bool_type);
7694 if (casted_value->type_entry->id == TypeTableEntryIdInvalid)
7695 return ira->codegen->builtin_types.entry_invalid;
7696
7697 if (casted_value->static_value.special != ConstValSpecialRuntime) {
7698 bool depends_on_compile_var = casted_value->static_value.depends_on_compile_var;
7699 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var);
7700 out_val->data.x_bool = !casted_value->static_value.data.x_bool;
7701 return bool_type;
7702 }
7703
7704 ir_build_bool_not_from(&ira->new_irb, &instruction->base, casted_value);
7705 return bool_type;
7706}
7707
76237708static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
76247709 switch (instruction->id) {
76257710 case IrInstructionIdInvalid:
......@@ -7730,6 +7815,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
77307815 return ir_analyze_instruction_div_exact(ira, (IrInstructionDivExact *)instruction);
77317816 case IrInstructionIdTruncate:
77327817 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction);
7818 case IrInstructionIdIntType:
7819 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
7820 case IrInstructionIdBoolNot:
7821 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction);
77337822 case IrInstructionIdCast:
77347823 case IrInstructionIdStructFieldPtr:
77357824 case IrInstructionIdEnumFieldPtr:
......@@ -7869,6 +7958,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
78697958 case IrInstructionIdEmbedFile:
78707959 case IrInstructionIdDivExact:
78717960 case IrInstructionIdTruncate:
7961 case IrInstructionIdIntType:
7962 case IrInstructionIdBoolNot:
78727963 return false;
78737964 case IrInstructionIdAsm:
78747965 {
......@@ -7880,45 +7971,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
78807971}
78817972
78827973// TODO port over all this commented out code into new IR way of doing things
7883//static TypeTableEntry *analyze_int_type(CodeGen *g, ImportTableEntry *import,
7884// BlockContext *context, AstNode *node)
7885//{
7886// AstNode **is_signed_node = &node->data.fn_call_expr.params.at(0);
7887// AstNode **bit_count_node = &node->data.fn_call_expr.params.at(1);
7888//
7889// TypeTableEntry *bool_type = g->builtin_types.entry_bool;
7890// TypeTableEntry *usize_type = g->builtin_types.entry_usize;
7891// TypeTableEntry *is_signed_type = analyze_expression(g, import, context, bool_type, *is_signed_node);
7892// TypeTableEntry *bit_count_type = analyze_expression(g, import, context, usize_type, *bit_count_node);
7893//
7894// if (is_signed_type->id == TypeTableEntryIdInvalid ||
7895// bit_count_type->id == TypeTableEntryIdInvalid)
7896// {
7897// return g->builtin_types.entry_invalid;
7898// }
7899//
7900// ConstExprValue *is_signed_val = &get_resolved_expr(*is_signed_node)->const_val;
7901// ConstExprValue *bit_count_val = &get_resolved_expr(*bit_count_node)->const_val;
7902//
7903// AstNode *bad_node = nullptr;
7904// if (!is_signed_val->ok) {
7905// bad_node = *is_signed_node;
7906// } else if (!bit_count_val->ok) {
7907// bad_node = *bit_count_node;
7908// }
7909// if (bad_node) {
7910// add_node_error(g, bad_node, buf_sprintf("unable to evaluate constant expression"));
7911// return g->builtin_types.entry_invalid;
7912// }
7913//
7914// bool depends_on_compile_var = is_signed_val->depends_on_compile_var || bit_count_val->depends_on_compile_var;
7915//
7916// TypeTableEntry *int_type = get_int_type(g, is_signed_val->data.x_bool,
7917// bit_count_val->data.x_bignum.data.x_uint);
7918// return resolve_expr_const_val_as_type(g, node, int_type, depends_on_compile_var);
7919//
7920//}
7921//
79227974//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
79237975// TypeTableEntry *expected_type, AstNode *node)
79247976//{
......@@ -8049,8 +8101,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
80498101// case BuiltinFnIdFrameAddress:
80508102// mark_impure_fn(g, context, node);
80518103// return builtin_fn->return_type;
8052// case BuiltinFnIdIntType:
8053// return analyze_int_type(g, import, context, node);
80548104// }
80558105// zig_unreachable();
80568106//}
......@@ -8215,34 +8265,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
82158265// return return_type;
82168266//}
82178267//
8218//static TypeTableEntry *analyze_logic_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
8219// AstNode *node)
8220//{
8221// assert(node->type == NodeTypeBinOpExpr);
8222// BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
8223//
8224// AstNode *op1 = node->data.bin_op_expr.op1;
8225// AstNode *op2 = node->data.bin_op_expr.op2;
8226// TypeTableEntry *op1_type = analyze_expression(g, import, context, g->builtin_types.entry_bool, op1);
8227// TypeTableEntry *op2_type = analyze_expression(g, import, context, g->builtin_types.entry_bool, op2);
8228//
8229// if (op1_type->id == TypeTableEntryIdInvalid ||
8230// op2_type->id == TypeTableEntryIdInvalid)
8231// {
8232// return g->builtin_types.entry_invalid;
8233// }
8234//
8235// ConstExprValue *op1_val = &get_resolved_expr(op1)->const_val;
8236// ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;
8237// if (!op1_val->ok || !op2_val->ok) {
8238// return g->builtin_types.entry_bool;
8239// }
8240//
8241// ConstExprValue *out_val = &get_resolved_expr(node)->const_val;
8242// eval_const_expr_bin_op(op1_val, op1_type, bin_op_type, op2_val, op2_type, out_val);
8243// return g->builtin_types.entry_bool;
8244//}
8245//
82468268//static TypeTableEntry *analyze_array_mult(CodeGen *g, ImportTableEntry *import, BlockContext *context,
82478269// TypeTableEntry *expected_type, AstNode *node)
82488270//{
......@@ -8402,7 +8424,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
84028424// switch (builtin_fn->id) {
84038425// case BuiltinFnIdInvalid:
84048426// case BuiltinFnIdTypeof:
8405// case BuiltinFnIdIntType:
84068427// zig_unreachable();
84078428// case BuiltinFnIdAddWithOverflow:
84088429// case BuiltinFnIdSubWithOverflow:
src/ir_print.cpp+19-2
......@@ -279,8 +279,6 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {
279279 switch (op_id) {
280280 case IrUnOpInvalid:
281281 zig_unreachable();
282 case IrUnOpBoolNot:
283 return "!";
284282 case IrUnOpBinNot:
285283 return "~";
286284 case IrUnOpNegation:
......@@ -755,6 +753,19 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction)
755753 fprintf(irp->f, ")");
756754}
757755
756static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
757 fprintf(irp->f, "@intType(");
758 ir_print_other_instruction(irp, instruction->is_signed);
759 fprintf(irp->f, ", ");
760 ir_print_other_instruction(irp, instruction->bit_count);
761 fprintf(irp->f, ")");
762}
763
764static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) {
765 fprintf(irp->f, "! ");
766 ir_print_other_instruction(irp, instruction->value);
767}
768
758769static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
759770 ir_print_prefix(irp, instruction);
760771 switch (instruction->id) {
......@@ -931,6 +942,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
931942 case IrInstructionIdTruncate:
932943 ir_print_truncate(irp, (IrInstructionTruncate *)instruction);
933944 break;
945 case IrInstructionIdIntType:
946 ir_print_int_type(irp, (IrInstructionIntType *)instruction);
947 break;
948 case IrInstructionIdBoolNot:
949 ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction);
950 break;
934951 }
935952 fprintf(irp->f, "\n");
936953}
test/self_hosted2.zig+30
......@@ -299,6 +299,35 @@ fn testTruncate(x: u32) -> u8 {
299299 @truncate(u8, x)
300300}
301301
302fn intTypeBuiltin() {
303 assert(@intType(true, 8) == i8);
304 assert(@intType(true, 16) == i16);
305 assert(@intType(true, 32) == i32);
306 assert(@intType(true, 64) == i64);
307
308 assert(@intType(false, 8) == u8);
309 assert(@intType(false, 16) == u16);
310 assert(@intType(false, 32) == u32);
311 assert(@intType(false, 64) == u64);
312
313 assert(i8.bit_count == 8);
314 assert(i16.bit_count == 16);
315 assert(i32.bit_count == 32);
316 assert(i64.bit_count == 64);
317
318 assert(i8.is_signed);
319 assert(i16.is_signed);
320 assert(i32.is_signed);
321 assert(i64.is_signed);
322 assert(isize.is_signed);
323
324 assert(!u8.is_signed);
325 assert(!u16.is_signed);
326 assert(!u32.is_signed);
327 assert(!u64.is_signed);
328 assert(!usize.is_signed);
329
330}
302331
303332fn assert(ok: bool) {
304333 if (!ok)
......@@ -331,6 +360,7 @@ fn runAllTests() {
331360 fence();
332361 exactDivision();
333362 truncate();
363 intTypeBuiltin();
334364}
335365
336366export nakedcc fn _start() -> unreachable {