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 {...@@ -1411,6 +1411,8 @@ enum IrInstructionId {
1411 IrInstructionIdFence,1411 IrInstructionIdFence,
1412 IrInstructionIdDivExact,1412 IrInstructionIdDivExact,
1413 IrInstructionIdTruncate,1413 IrInstructionIdTruncate,
1414 IrInstructionIdIntType,
1415 IrInstructionIdBoolNot,
1414};1416};
14151417
1416struct IrInstruction {1418struct IrInstruction {
...@@ -1481,7 +1483,6 @@ struct IrInstructionPhi {...@@ -1481,7 +1483,6 @@ struct IrInstructionPhi {
14811483
1482enum IrUnOp {1484enum IrUnOp {
1483 IrUnOpInvalid,1485 IrUnOpInvalid,
1484 IrUnOpBoolNot,
1485 IrUnOpBinNot,1486 IrUnOpBinNot,
1486 IrUnOpNegation,1487 IrUnOpNegation,
1487 IrUnOpNegationWrap,1488 IrUnOpNegationWrap,
...@@ -1900,6 +1901,19 @@ struct IrInstructionTruncate {...@@ -1900,6 +1901,19 @@ struct IrInstructionTruncate {
1900 IrInstruction *target;1901 IrInstruction *target;
1901};1902};
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
1903enum LValPurpose {1917enum LValPurpose {
1904 LValPurposeNone,1918 LValPurposeNone,
1905 LValPurposeAssign,1919 LValPurposeAssign,
src/analyze.cpp+11
...@@ -2809,3 +2809,14 @@ ConstExprValue *create_const_enum_tag(uint64_t tag) {...@@ -2809,3 +2809,14 @@ ConstExprValue *create_const_enum_tag(uint64_t tag) {
2809 init_const_enum_tag(const_val, tag);2809 init_const_enum_tag(const_val, tag);
2810 return const_val;2810 return const_val;
2811}2811}
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);...@@ -98,4 +98,7 @@ ConstExprValue *create_const_float(double value);
98void init_const_enum_tag(ConstExprValue *const_val, uint64_t tag);98void init_const_enum_tag(ConstExprValue *const_val, uint64_t tag);
99ConstExprValue *create_const_enum_tag(uint64_t tag);99ConstExprValue *create_const_enum_tag(uint64_t tag);
100100
101void init_const_bool(ConstExprValue *const_val, bool value);
102ConstExprValue *create_const_bool(bool value);
103
101#endif104#endif
src/codegen.cpp+9-5
...@@ -1230,11 +1230,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1230,11 +1230,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1230 zig_unreachable();1230 zig_unreachable();
1231 }1231 }
1232 }1232 }
1233 case IrUnOpBoolNot:
1234 {
1235 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
1236 return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, "");
1237 }
1238 case IrUnOpBinNot:1233 case IrUnOpBinNot:
1239 return LLVMBuildNot(g->builder, expr, "");1234 return LLVMBuildNot(g->builder, expr, "");
1240 case IrUnOpAddressOf:1235 case IrUnOpAddressOf:
...@@ -1339,6 +1334,12 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1339,6 +1334,12 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1339 zig_unreachable();1334 zig_unreachable();
1340}1335}
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
1342static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,1343static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1343 IrInstructionDeclVar *decl_var_instruction)1344 IrInstructionDeclVar *decl_var_instruction)
1344{1345{
...@@ -1927,6 +1928,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1927,6 +1928,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1927 case IrInstructionIdCDefine:1928 case IrInstructionIdCDefine:
1928 case IrInstructionIdCUndef:1929 case IrInstructionIdCUndef:
1929 case IrInstructionIdEmbedFile:1930 case IrInstructionIdEmbedFile:
1931 case IrInstructionIdIntType:
1930 zig_unreachable();1932 zig_unreachable();
1931 case IrInstructionIdReturn:1933 case IrInstructionIdReturn:
1932 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);1934 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -1984,6 +1986,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1984,6 +1986,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1984 return ir_render_div_exact(g, executable, (IrInstructionDivExact *)instruction);1986 return ir_render_div_exact(g, executable, (IrInstructionDivExact *)instruction);
1985 case IrInstructionIdTruncate:1987 case IrInstructionIdTruncate:
1986 return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction);1988 return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction);
1989 case IrInstructionIdBoolNot:
1990 return ir_render_bool_not(g, executable, (IrInstructionBoolNot *)instruction);
1987 case IrInstructionIdSwitchVar:1991 case IrInstructionIdSwitchVar:
1988 case IrInstructionIdContainerInitList:1992 case IrInstructionIdContainerInitList:
1989 case IrInstructionIdStructInit:1993 case IrInstructionIdStructInit:
src/ir.cpp+133-112
...@@ -363,6 +363,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) {...@@ -363,6 +363,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) {
363 return IrInstructionIdTruncate;363 return IrInstructionIdTruncate;
364}364}
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
366template<typename T>374template<typename T>
367static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {375static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
368 T *special_instruction = allocate<T>(1);376 T *special_instruction = allocate<T>(1);
...@@ -1455,6 +1463,32 @@ static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_...@@ -1455,6 +1463,32 @@ static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_
1455 return new_instruction;1463 return new_instruction;
1456}1464}
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
1458static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,1492static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
1459 bool gen_error_defers, bool gen_maybe_defers)1493 bool gen_error_defers, bool gen_maybe_defers)
1460{1494{
...@@ -2262,6 +2296,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -2262,6 +2296,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
22622296
2263 return ir_build_truncate(irb, scope, node, arg0_value, arg1_value);2297 return ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
2264 }2298 }
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 }
2265 case BuiltinFnIdMemcpy:2313 case BuiltinFnIdMemcpy:
2266 case BuiltinFnIdMemset:2314 case BuiltinFnIdMemset:
2267 case BuiltinFnIdAlignof:2315 case BuiltinFnIdAlignof:
...@@ -2273,7 +2321,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -2273,7 +2321,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
2273 case BuiltinFnIdBreakpoint:2321 case BuiltinFnIdBreakpoint:
2274 case BuiltinFnIdReturnAddress:2322 case BuiltinFnIdReturnAddress:
2275 case BuiltinFnIdFrameAddress:2323 case BuiltinFnIdFrameAddress:
2276 case BuiltinFnIdIntType:
2277 zig_panic("TODO IR gen more builtin functions");2324 zig_panic("TODO IR gen more builtin functions");
2278 }2325 }
2279 zig_unreachable();2326 zig_unreachable();
...@@ -2379,6 +2426,28 @@ static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, Scope *scope...@@ -2379,6 +2426,28 @@ static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, Scope *scope
2379 return unwrapped_ptr;2426 return unwrapped_ptr;
2380}2427}
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
2382static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {2451static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
2383 assert(node->type == NodeTypePrefixOpExpr);2452 assert(node->type == NodeTypePrefixOpExpr);
23842453
...@@ -2388,7 +2457,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -2388,7 +2457,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
2388 case PrefixOpInvalid:2457 case PrefixOpInvalid:
2389 zig_unreachable();2458 zig_unreachable();
2390 case PrefixOpBoolNot:2459 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);
2392 case PrefixOpBinNot:2461 case PrefixOpBinNot:
2393 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot);2462 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot);
2394 case PrefixOpNegation:2463 case PrefixOpNegation:
...@@ -3124,17 +3193,6 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -3124,17 +3193,6 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod
3124 return ir_build_br(irb, scope, node, dest_block, is_inline);3193 return ir_build_br(irb, scope, node, dest_block, is_inline);
3125}3194}
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
3138static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {3196static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
3139 assert(node->type == NodeTypeTypeLiteral);3197 assert(node->type == NodeTypeTypeLiteral);
3140 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type);3198 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...@@ -5136,31 +5194,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
5136 }5194 }
5137}5195}
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
5164static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {5197static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
5165 assert(un_op_instruction->op_id == IrUnOpError);5198 assert(un_op_instruction->op_id == IrUnOpError);
5166 IrInstruction *value = un_op_instruction->value->other;5199 IrInstruction *value = un_op_instruction->value->other;
...@@ -5425,8 +5458,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio...@@ -5425,8 +5458,6 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio
5425 switch (op_id) {5458 switch (op_id) {
5426 case IrUnOpInvalid:5459 case IrUnOpInvalid:
5427 zig_unreachable();5460 zig_unreachable();
5428 case IrUnOpBoolNot:
5429 return ir_analyze_unary_bool_not(ira, un_op_instruction);
5430 case IrUnOpBinNot:5461 case IrUnOpBinNot:
5431 zig_panic("TODO analyze PrefixOpBinNot");5462 zig_panic("TODO analyze PrefixOpBinNot");
5432 //{5463 //{
...@@ -5961,9 +5992,22 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5961,9 +5992,22 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5961 buf_sprintf("use of undeclared error value '%s'", buf_ptr(field_name)));5992 buf_sprintf("use of undeclared error value '%s'", buf_ptr(field_name)));
5962 return ira->codegen->builtin_types.entry_invalid;5993 return ira->codegen->builtin_types.entry_invalid;
5963 } else if (child_type->id == TypeTableEntryIdInt) {5994 } 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 }
5965 } else {6009 } else {
5966 add_node_error(ira->codegen, source_node,6010 ir_add_error(ira, &field_ptr_instruction->base,
5967 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));6011 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
5968 return ira->codegen->builtin_types.entry_invalid;6012 return ira->codegen->builtin_types.entry_invalid;
5969 }6013 }
...@@ -7620,6 +7664,47 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc...@@ -7620,6 +7664,47 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc
7620 return dest_type;7664 return dest_type;
7621}7665}
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
7623static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {7708static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
7624 switch (instruction->id) {7709 switch (instruction->id) {
7625 case IrInstructionIdInvalid:7710 case IrInstructionIdInvalid:
...@@ -7730,6 +7815,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -7730,6 +7815,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
7730 return ir_analyze_instruction_div_exact(ira, (IrInstructionDivExact *)instruction);7815 return ir_analyze_instruction_div_exact(ira, (IrInstructionDivExact *)instruction);
7731 case IrInstructionIdTruncate:7816 case IrInstructionIdTruncate:
7732 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction);7817 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);
7733 case IrInstructionIdCast:7822 case IrInstructionIdCast:
7734 case IrInstructionIdStructFieldPtr:7823 case IrInstructionIdStructFieldPtr:
7735 case IrInstructionIdEnumFieldPtr:7824 case IrInstructionIdEnumFieldPtr:
...@@ -7869,6 +7958,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -7869,6 +7958,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
7869 case IrInstructionIdEmbedFile:7958 case IrInstructionIdEmbedFile:
7870 case IrInstructionIdDivExact:7959 case IrInstructionIdDivExact:
7871 case IrInstructionIdTruncate:7960 case IrInstructionIdTruncate:
7961 case IrInstructionIdIntType:
7962 case IrInstructionIdBoolNot:
7872 return false;7963 return false;
7873 case IrInstructionIdAsm:7964 case IrInstructionIdAsm:
7874 {7965 {
...@@ -7880,45 +7971,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -7880,45 +7971,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
7880}7971}
78817972
7882// TODO port over all this commented out code into new IR way of doing things7973// 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//
7922//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,7974//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
7923// TypeTableEntry *expected_type, AstNode *node)7975// TypeTableEntry *expected_type, AstNode *node)
7924//{7976//{
...@@ -8049,8 +8101,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -8049,8 +8101,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
8049// case BuiltinFnIdFrameAddress:8101// case BuiltinFnIdFrameAddress:
8050// mark_impure_fn(g, context, node);8102// mark_impure_fn(g, context, node);
8051// return builtin_fn->return_type;8103// return builtin_fn->return_type;
8052// case BuiltinFnIdIntType:
8053// return analyze_int_type(g, import, context, node);
8054// }8104// }
8055// zig_unreachable();8105// zig_unreachable();
8056//}8106//}
...@@ -8215,34 +8265,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -8215,34 +8265,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
8215// return return_type;8265// return return_type;
8216//}8266//}
8217//8267//
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//
8246//static TypeTableEntry *analyze_array_mult(CodeGen *g, ImportTableEntry *import, BlockContext *context,8268//static TypeTableEntry *analyze_array_mult(CodeGen *g, ImportTableEntry *import, BlockContext *context,
8247// TypeTableEntry *expected_type, AstNode *node)8269// TypeTableEntry *expected_type, AstNode *node)
8248//{8270//{
...@@ -8402,7 +8424,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -8402,7 +8424,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
8402// switch (builtin_fn->id) {8424// switch (builtin_fn->id) {
8403// case BuiltinFnIdInvalid:8425// case BuiltinFnIdInvalid:
8404// case BuiltinFnIdTypeof:8426// case BuiltinFnIdTypeof:
8405// case BuiltinFnIdIntType:
8406// zig_unreachable();8427// zig_unreachable();
8407// case BuiltinFnIdAddWithOverflow:8428// case BuiltinFnIdAddWithOverflow:
8408// case BuiltinFnIdSubWithOverflow:8429// case BuiltinFnIdSubWithOverflow:
src/ir_print.cpp+19-2
...@@ -279,8 +279,6 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {...@@ -279,8 +279,6 @@ static const char *ir_un_op_id_str(IrUnOp op_id) {
279 switch (op_id) {279 switch (op_id) {
280 case IrUnOpInvalid:280 case IrUnOpInvalid:
281 zig_unreachable();281 zig_unreachable();
282 case IrUnOpBoolNot:
283 return "!";
284 case IrUnOpBinNot:282 case IrUnOpBinNot:
285 return "~";283 return "~";
286 case IrUnOpNegation:284 case IrUnOpNegation:
...@@ -755,6 +753,19 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction)...@@ -755,6 +753,19 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction)
755 fprintf(irp->f, ")");753 fprintf(irp->f, ")");
756}754}
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
758static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {769static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
759 ir_print_prefix(irp, instruction);770 ir_print_prefix(irp, instruction);
760 switch (instruction->id) {771 switch (instruction->id) {
...@@ -931,6 +942,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -931,6 +942,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
931 case IrInstructionIdTruncate:942 case IrInstructionIdTruncate:
932 ir_print_truncate(irp, (IrInstructionTruncate *)instruction);943 ir_print_truncate(irp, (IrInstructionTruncate *)instruction);
933 break;944 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;
934 }951 }
935 fprintf(irp->f, "\n");952 fprintf(irp->f, "\n");
936}953}
test/self_hosted2.zig+30
...@@ -299,6 +299,35 @@ fn testTruncate(x: u32) -> u8 {...@@ -299,6 +299,35 @@ fn testTruncate(x: u32) -> u8 {
299 @truncate(u8, x)299 @truncate(u8, x)
300}300}
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
303fn assert(ok: bool) {332fn assert(ok: bool) {
304 if (!ok)333 if (!ok)
...@@ -331,6 +360,7 @@ fn runAllTests() {...@@ -331,6 +360,7 @@ fn runAllTests() {
331 fence();360 fence();
332 exactDivision();361 exactDivision();
333 truncate();362 truncate();
363 intTypeBuiltin();
334}364}
335365
336export nakedcc fn _start() -> unreachable {366export nakedcc fn _start() -> unreachable {