simple add function works with IR
parent
633781e31d
commit
cd1bd78aa9
|
@ -1420,6 +1420,7 @@ enum IrInstructionId {
|
||||||
IrInstructionIdBuiltinCall,
|
IrInstructionIdBuiltinCall,
|
||||||
IrInstructionIdConst,
|
IrInstructionIdConst,
|
||||||
IrInstructionIdReturn,
|
IrInstructionIdReturn,
|
||||||
|
IrInstructionIdCast,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstruction {
|
struct IrInstruction {
|
||||||
|
@ -1539,5 +1540,12 @@ struct IrInstructionReturn {
|
||||||
IrInstruction *value;
|
IrInstruction *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IrInstructionCast {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *value;
|
||||||
|
IrInstruction *dest_type;
|
||||||
|
bool is_implicit;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,10 +42,8 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
|
||||||
TypeTableEntry *expected_type, uint64_t x, bool depends_on_compile_var);
|
TypeTableEntry *expected_type, uint64_t x, bool depends_on_compile_var);
|
||||||
static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value,
|
static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value,
|
||||||
bool depends_on_compile_var);
|
bool depends_on_compile_var);
|
||||||
static AstNode *find_decl(BlockContext *context, Buf *name);
|
|
||||||
static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
|
static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
|
||||||
bool pointer_only, BlockContext *block_context, bool depends_on_compile_var);
|
bool pointer_only, BlockContext *block_context, bool depends_on_compile_var);
|
||||||
static TopLevelDecl *get_as_top_level_decl(AstNode *node);
|
|
||||||
static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTableEntry *import,
|
static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTableEntry *import,
|
||||||
BlockContext *context, AstNode *source_node,
|
BlockContext *context, AstNode *source_node,
|
||||||
AstNodeVariableDeclaration *variable_declaration,
|
AstNodeVariableDeclaration *variable_declaration,
|
||||||
|
@ -1757,7 +1755,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
|
||||||
node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
|
node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
|
void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
|
||||||
TopLevelDecl *tld = get_as_top_level_decl(node);
|
TopLevelDecl *tld = get_as_top_level_decl(node);
|
||||||
if (tld->resolution != TldResolutionUnresolved) {
|
if (tld->resolution != TldResolutionUnresolved) {
|
||||||
return;
|
return;
|
||||||
|
@ -1978,7 +1976,7 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
||||||
if (expected_type == actual_type)
|
if (expected_type == actual_type)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -2302,7 +2300,7 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, ImportTableEntry *
|
||||||
return g->builtin_types.entry_invalid;
|
return g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEntry *import,
|
TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEntry *import,
|
||||||
BlockContext *block_context, AstNode *parent_source_node,
|
BlockContext *block_context, AstNode *parent_source_node,
|
||||||
AstNode **child_nodes, TypeTableEntry **child_types, size_t child_count)
|
AstNode **child_nodes, TypeTableEntry **child_types, size_t child_count)
|
||||||
{
|
{
|
||||||
|
@ -2358,7 +2356,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AstNode *find_decl(BlockContext *context, Buf *name) {
|
AstNode *find_decl(BlockContext *context, Buf *name) {
|
||||||
while (context) {
|
while (context) {
|
||||||
auto entry = context->decl_table.maybe_get(name);
|
auto entry = context->decl_table.maybe_get(name);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
|
@ -2369,7 +2367,7 @@ static AstNode *find_decl(BlockContext *context, Buf *name) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name) {
|
VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name) {
|
||||||
BlockContext *context = orig_context;
|
BlockContext *context = orig_context;
|
||||||
while (context) {
|
while (context) {
|
||||||
auto entry = context->var_table.maybe_get(name);
|
auto entry = context->var_table.maybe_get(name);
|
||||||
|
@ -3248,10 +3246,6 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod
|
||||||
static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||||
TypeTableEntry *expected_type, AstNode *node, bool pointer_only)
|
TypeTableEntry *expected_type, AstNode *node, bool pointer_only)
|
||||||
{
|
{
|
||||||
if (node->data.symbol_expr.override_type_entry) {
|
|
||||||
return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buf *variable_name = node->data.symbol_expr.symbol;
|
Buf *variable_name = node->data.symbol_expr.symbol;
|
||||||
|
|
||||||
auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
|
auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
|
||||||
|
@ -4091,11 +4085,6 @@ static TypeTableEntry *analyze_this_literal_expr(CodeGen *g, ImportTableEntry *i
|
||||||
static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
|
static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||||
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
||||||
{
|
{
|
||||||
if (node->data.number_literal.overflow) {
|
|
||||||
add_node_error(g, node, buf_sprintf("number literal too large to be represented in any type"));
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve_expr_const_val_as_bignum(g, node, expected_type, node->data.number_literal.bignum, false);
|
return resolve_expr_const_val_as_bignum(g, node, expected_type, node->data.number_literal.bignum, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7536,7 +7525,7 @@ Expr *get_resolved_expr(AstNode *node) {
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
|
TopLevelDecl *get_as_top_level_decl(AstNode *node) {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case NodeTypeVariableDeclaration:
|
case NodeTypeVariableDeclaration:
|
||||||
return &node->data.variable_declaration.top_level_decl;
|
return &node->data.variable_declaration.top_level_decl;
|
||||||
|
|
|
@ -45,4 +45,14 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
|
||||||
|
|
||||||
AstNode *first_executing_node(AstNode *node);
|
AstNode *first_executing_node(AstNode *node);
|
||||||
|
|
||||||
|
TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEntry *import,
|
||||||
|
BlockContext *block_context, AstNode *parent_source_node,
|
||||||
|
AstNode **child_nodes, TypeTableEntry **child_types, size_t child_count);
|
||||||
|
|
||||||
|
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
|
||||||
|
VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name);
|
||||||
|
AstNode *find_decl(BlockContext *context, Buf *name);
|
||||||
|
void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);
|
||||||
|
TopLevelDecl *get_as_top_level_decl(AstNode *node);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
114
src/codegen.cpp
114
src/codegen.cpp
|
@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
||||||
g->is_test_build = false;
|
g->is_test_build = false;
|
||||||
g->want_h_file = true;
|
g->want_h_file = true;
|
||||||
|
|
||||||
g->invalid_instruction = allocate<IrInstruction>(1);
|
|
||||||
|
|
||||||
// the error.Ok value
|
// the error.Ok value
|
||||||
g->error_decls.append(nullptr);
|
g->error_decls.append(nullptr);
|
||||||
|
|
||||||
|
@ -252,10 +250,6 @@ static void set_debug_source_node(CodeGen *g, AstNode *node) {
|
||||||
ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->block_context->di_scope);
|
ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, node->block_context->di_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_set_debug(CodeGen *g, IrInstruction *instruction) {
|
|
||||||
set_debug_source_node(g, instruction->source_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_debug_source_node(CodeGen *g) {
|
static void clear_debug_source_node(CodeGen *g) {
|
||||||
ZigLLVMClearCurrentDebugLocation(g->builder);
|
ZigLLVMClearCurrentDebugLocation(g->builder);
|
||||||
}
|
}
|
||||||
|
@ -375,6 +369,10 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) {
|
||||||
return want_debug_safety_recursive(g, node->block_context);
|
return want_debug_safety_recursive(g, node->block_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
|
||||||
|
return want_debug_safety(g, instruction->source_node);
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_debug_safety_crash(CodeGen *g) {
|
static void gen_debug_safety_crash(CodeGen *g) {
|
||||||
LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
|
LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
|
||||||
LLVMBuildUnreachable(g->builder);
|
LLVMBuildUnreachable(g->builder);
|
||||||
|
@ -2800,12 +2798,104 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
|
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
|
||||||
ir_set_debug(g, &return_instruction->base);
|
|
||||||
LLVMBuildRet(g->builder, return_instruction->value->llvm_value);
|
LLVMBuildRet(g->builder, return_instruction->value->llvm_value);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef ir_render_load_var(CodeGen *g, IrExecutable *executable,
|
||||||
|
IrInstructionLoadVar *load_var_instruction)
|
||||||
|
{
|
||||||
|
VariableTableEntry *var = load_var_instruction->var;
|
||||||
|
if (!type_has_bits(var->type))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
assert(var->value_ref);
|
||||||
|
return get_handle_value(g, load_var_instruction->base.source_node, var->value_ref, var->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable,
|
||||||
|
IrInstructionBinOp *bin_op_instruction)
|
||||||
|
{
|
||||||
|
IrBinOp op_id = bin_op_instruction->op_id;
|
||||||
|
LLVMValueRef op1 = bin_op_instruction->op1->llvm_value;
|
||||||
|
LLVMValueRef op2 = bin_op_instruction->op2->llvm_value;
|
||||||
|
if (op_id == IrBinOpBoolOr) {
|
||||||
|
return LLVMBuildOr(g->builder, op1, op2, "");
|
||||||
|
} else if (op_id == IrBinOpBoolAnd) {
|
||||||
|
return LLVMBuildAnd(g->builder, op1, op2, "");
|
||||||
|
} else {
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef ir_render_bin_op_add(CodeGen *g, IrExecutable *executable,
|
||||||
|
IrInstructionBinOp *bin_op_instruction)
|
||||||
|
{
|
||||||
|
IrBinOp op_id = bin_op_instruction->op_id;
|
||||||
|
IrInstruction *op1 = bin_op_instruction->op1;
|
||||||
|
IrInstruction *op2 = bin_op_instruction->op2;
|
||||||
|
|
||||||
|
assert(op1->type_entry == op2->type_entry);
|
||||||
|
|
||||||
|
if (op1->type_entry->id == TypeTableEntryIdFloat) {
|
||||||
|
return LLVMBuildFAdd(g->builder, op1->llvm_value, op2->llvm_value, "");
|
||||||
|
} else if (op1->type_entry->id == TypeTableEntryIdInt) {
|
||||||
|
bool is_wrapping = (op_id == IrBinOpAddWrap);
|
||||||
|
if (is_wrapping) {
|
||||||
|
return LLVMBuildAdd(g->builder, op1->llvm_value, op2->llvm_value, "");
|
||||||
|
} else if (ir_want_debug_safety(g, &bin_op_instruction->base)) {
|
||||||
|
return gen_overflow_op(g, op1->type_entry, AddSubMulAdd, op1->llvm_value, op2->llvm_value);
|
||||||
|
} else if (op1->type_entry->data.integral.is_signed) {
|
||||||
|
return LLVMBuildNSWAdd(g->builder, op1->llvm_value, op2->llvm_value, "");
|
||||||
|
} else {
|
||||||
|
return LLVMBuildNUWAdd(g->builder, op1->llvm_value, op2->llvm_value, "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
|
||||||
|
IrInstructionBinOp *bin_op_instruction)
|
||||||
|
{
|
||||||
|
IrBinOp op_id = bin_op_instruction->op_id;
|
||||||
|
switch (op_id) {
|
||||||
|
case IrBinOpInvalid:
|
||||||
|
case IrBinOpArrayCat:
|
||||||
|
case IrBinOpArrayMult:
|
||||||
|
zig_unreachable();
|
||||||
|
case IrBinOpBoolOr:
|
||||||
|
case IrBinOpBoolAnd:
|
||||||
|
return ir_render_bin_op_bool(g, executable, bin_op_instruction);
|
||||||
|
case IrBinOpCmpEq:
|
||||||
|
case IrBinOpCmpNotEq:
|
||||||
|
case IrBinOpCmpLessThan:
|
||||||
|
case IrBinOpCmpGreaterThan:
|
||||||
|
case IrBinOpCmpLessOrEq:
|
||||||
|
case IrBinOpCmpGreaterOrEq:
|
||||||
|
zig_panic("TODO bin op cmp");
|
||||||
|
case IrBinOpAdd:
|
||||||
|
case IrBinOpAddWrap:
|
||||||
|
return ir_render_bin_op_add(g, executable, bin_op_instruction);
|
||||||
|
case IrBinOpBinOr:
|
||||||
|
case IrBinOpBinXor:
|
||||||
|
case IrBinOpBinAnd:
|
||||||
|
case IrBinOpBitShiftLeft:
|
||||||
|
case IrBinOpBitShiftLeftWrap:
|
||||||
|
case IrBinOpBitShiftRight:
|
||||||
|
case IrBinOpSub:
|
||||||
|
case IrBinOpSubWrap:
|
||||||
|
case IrBinOpMult:
|
||||||
|
case IrBinOpMultWrap:
|
||||||
|
case IrBinOpDiv:
|
||||||
|
case IrBinOpMod:
|
||||||
|
zig_panic("TODO render more bin ops to LLVM");
|
||||||
|
}
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
|
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
|
||||||
|
set_debug_source_node(g, instruction->source_node);
|
||||||
switch (instruction->id) {
|
switch (instruction->id) {
|
||||||
case IrInstructionIdInvalid:
|
case IrInstructionIdInvalid:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
|
@ -2813,14 +2903,17 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||||
return gen_const_val(g, instruction->type_entry, &instruction->static_value);
|
return gen_const_val(g, instruction->type_entry, &instruction->static_value);
|
||||||
case IrInstructionIdReturn:
|
case IrInstructionIdReturn:
|
||||||
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
|
||||||
|
case IrInstructionIdLoadVar:
|
||||||
|
return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction);
|
||||||
|
case IrInstructionIdBinOp:
|
||||||
|
return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction);
|
||||||
case IrInstructionIdCondBr:
|
case IrInstructionIdCondBr:
|
||||||
case IrInstructionIdSwitchBr:
|
case IrInstructionIdSwitchBr:
|
||||||
case IrInstructionIdPhi:
|
case IrInstructionIdPhi:
|
||||||
case IrInstructionIdBinOp:
|
|
||||||
case IrInstructionIdLoadVar:
|
|
||||||
case IrInstructionIdStoreVar:
|
case IrInstructionIdStoreVar:
|
||||||
case IrInstructionIdCall:
|
case IrInstructionIdCall:
|
||||||
case IrInstructionIdBuiltinCall:
|
case IrInstructionIdBuiltinCall:
|
||||||
|
case IrInstructionIdCast:
|
||||||
zig_panic("TODO render more IR instructions to LLVM");
|
zig_panic("TODO render more IR instructions to LLVM");
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
|
@ -5013,6 +5106,9 @@ static void init(CodeGen *g, Buf *source_path) {
|
||||||
|
|
||||||
define_builtin_types(g);
|
define_builtin_types(g);
|
||||||
define_builtin_fns(g);
|
define_builtin_fns(g);
|
||||||
|
|
||||||
|
g->invalid_instruction = allocate<IrInstruction>(1);
|
||||||
|
g->invalid_instruction->type_entry = g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {
|
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code) {
|
||||||
|
|
855
src/ir.cpp
855
src/ir.cpp
File diff suppressed because it is too large
Load Diff
136
src/ir_print.cpp
136
src/ir_print.cpp
|
@ -25,12 +25,24 @@ static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instructio
|
||||||
|
|
||||||
static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {
|
static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {
|
||||||
ir_print_prefix(irp, &const_instruction->base);
|
ir_print_prefix(irp, &const_instruction->base);
|
||||||
switch (const_instruction->base.type_entry->id) {
|
TypeTableEntry *type_entry = const_instruction->base.type_entry;
|
||||||
|
fprintf(irp->f, "%s ", buf_ptr(&type_entry->name));
|
||||||
|
switch (type_entry->id) {
|
||||||
case TypeTableEntryIdInvalid:
|
case TypeTableEntryIdInvalid:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case TypeTableEntryIdVoid:
|
case TypeTableEntryIdVoid:
|
||||||
fprintf(irp->f, "void\n");
|
fprintf(irp->f, "%s\n", "void");
|
||||||
break;
|
break;
|
||||||
|
case TypeTableEntryIdNumLitFloat:
|
||||||
|
fprintf(irp->f, "%f\n", const_instruction->base.static_value.data.x_bignum.data.x_float);
|
||||||
|
break;
|
||||||
|
case TypeTableEntryIdNumLitInt:
|
||||||
|
{
|
||||||
|
BigNum *bignum = &const_instruction->base.static_value.data.x_bignum;
|
||||||
|
const char *negative_str = bignum->is_negative ? "-" : "";
|
||||||
|
fprintf(irp->f, "%s%llu\n", negative_str, bignum->data.x_uint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TypeTableEntryIdVar:
|
case TypeTableEntryIdVar:
|
||||||
case TypeTableEntryIdMetaType:
|
case TypeTableEntryIdMetaType:
|
||||||
case TypeTableEntryIdBool:
|
case TypeTableEntryIdBool:
|
||||||
|
@ -40,8 +52,6 @@ static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction)
|
||||||
case TypeTableEntryIdPointer:
|
case TypeTableEntryIdPointer:
|
||||||
case TypeTableEntryIdArray:
|
case TypeTableEntryIdArray:
|
||||||
case TypeTableEntryIdStruct:
|
case TypeTableEntryIdStruct:
|
||||||
case TypeTableEntryIdNumLitFloat:
|
|
||||||
case TypeTableEntryIdNumLitInt:
|
|
||||||
case TypeTableEntryIdUndefLit:
|
case TypeTableEntryIdUndefLit:
|
||||||
case TypeTableEntryIdNullLit:
|
case TypeTableEntryIdNullLit:
|
||||||
case TypeTableEntryIdMaybe:
|
case TypeTableEntryIdMaybe:
|
||||||
|
@ -58,6 +68,104 @@ static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *ir_bin_op_id_str(IrBinOp op_id) {
|
||||||
|
switch (op_id) {
|
||||||
|
case IrBinOpInvalid:
|
||||||
|
zig_unreachable();
|
||||||
|
case IrBinOpBoolOr:
|
||||||
|
return "BoolOr";
|
||||||
|
case IrBinOpBoolAnd:
|
||||||
|
return "BoolAnd";
|
||||||
|
case IrBinOpCmpEq:
|
||||||
|
return "==";
|
||||||
|
case IrBinOpCmpNotEq:
|
||||||
|
return "!=";
|
||||||
|
case IrBinOpCmpLessThan:
|
||||||
|
return "<";
|
||||||
|
case IrBinOpCmpGreaterThan:
|
||||||
|
return ">";
|
||||||
|
case IrBinOpCmpLessOrEq:
|
||||||
|
return "<=";
|
||||||
|
case IrBinOpCmpGreaterOrEq:
|
||||||
|
return ">=";
|
||||||
|
case IrBinOpBinOr:
|
||||||
|
return "|";
|
||||||
|
case IrBinOpBinXor:
|
||||||
|
return "^";
|
||||||
|
case IrBinOpBinAnd:
|
||||||
|
return "&";
|
||||||
|
case IrBinOpBitShiftLeft:
|
||||||
|
return "<<";
|
||||||
|
case IrBinOpBitShiftLeftWrap:
|
||||||
|
return "<<%";
|
||||||
|
case IrBinOpBitShiftRight:
|
||||||
|
return ">>";
|
||||||
|
case IrBinOpAdd:
|
||||||
|
return "+";
|
||||||
|
case IrBinOpAddWrap:
|
||||||
|
return "+%";
|
||||||
|
case IrBinOpSub:
|
||||||
|
return "-";
|
||||||
|
case IrBinOpSubWrap:
|
||||||
|
return "-%";
|
||||||
|
case IrBinOpMult:
|
||||||
|
return "*";
|
||||||
|
case IrBinOpMultWrap:
|
||||||
|
return "*%";
|
||||||
|
case IrBinOpDiv:
|
||||||
|
return "/";
|
||||||
|
case IrBinOpMod:
|
||||||
|
return "%";
|
||||||
|
case IrBinOpArrayCat:
|
||||||
|
return "++";
|
||||||
|
case IrBinOpArrayMult:
|
||||||
|
return "**";
|
||||||
|
}
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ir_print_bin_op(IrPrint *irp, IrInstructionBinOp *bin_op_instruction) {
|
||||||
|
ir_print_prefix(irp, &bin_op_instruction->base);
|
||||||
|
fprintf(irp->f, "#%zu %s #%zu\n",
|
||||||
|
bin_op_instruction->op1->debug_id,
|
||||||
|
ir_bin_op_id_str(bin_op_instruction->op_id),
|
||||||
|
bin_op_instruction->op2->debug_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ir_print_load_var(IrPrint *irp, IrInstructionLoadVar *load_var_instruction) {
|
||||||
|
ir_print_prefix(irp, &load_var_instruction->base);
|
||||||
|
fprintf(irp->f, "%s\n",
|
||||||
|
buf_ptr(&load_var_instruction->var->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
|
switch (instruction->id) {
|
||||||
|
case IrInstructionIdInvalid:
|
||||||
|
zig_unreachable();
|
||||||
|
case IrInstructionIdReturn:
|
||||||
|
ir_print_return(irp, (IrInstructionReturn *)instruction);
|
||||||
|
break;
|
||||||
|
case IrInstructionIdConst:
|
||||||
|
ir_print_const(irp, (IrInstructionConst *)instruction);
|
||||||
|
break;
|
||||||
|
case IrInstructionIdBinOp:
|
||||||
|
ir_print_bin_op(irp, (IrInstructionBinOp *)instruction);
|
||||||
|
break;
|
||||||
|
case IrInstructionIdLoadVar:
|
||||||
|
ir_print_load_var(irp, (IrInstructionLoadVar *)instruction);
|
||||||
|
break;
|
||||||
|
case IrInstructionIdCondBr:
|
||||||
|
case IrInstructionIdSwitchBr:
|
||||||
|
case IrInstructionIdPhi:
|
||||||
|
case IrInstructionIdStoreVar:
|
||||||
|
case IrInstructionIdCall:
|
||||||
|
case IrInstructionIdBuiltinCall:
|
||||||
|
case IrInstructionIdCast:
|
||||||
|
zig_panic("TODO print more IR instructions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
|
void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
|
||||||
IrPrint ir_print = {};
|
IrPrint ir_print = {};
|
||||||
IrPrint *irp = &ir_print;
|
IrPrint *irp = &ir_print;
|
||||||
|
@ -70,25 +178,7 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
|
||||||
for (IrInstruction *instruction = current_block->first; instruction != nullptr;
|
for (IrInstruction *instruction = current_block->first; instruction != nullptr;
|
||||||
instruction = instruction->next)
|
instruction = instruction->next)
|
||||||
{
|
{
|
||||||
switch (instruction->id) {
|
ir_print_instruction(irp, instruction);
|
||||||
case IrInstructionIdInvalid:
|
|
||||||
zig_unreachable();
|
|
||||||
case IrInstructionIdReturn:
|
|
||||||
ir_print_return(irp, (IrInstructionReturn *)instruction);
|
|
||||||
break;
|
|
||||||
case IrInstructionIdConst:
|
|
||||||
ir_print_const(irp, (IrInstructionConst *)instruction);
|
|
||||||
break;
|
|
||||||
case IrInstructionIdCondBr:
|
|
||||||
case IrInstructionIdSwitchBr:
|
|
||||||
case IrInstructionIdPhi:
|
|
||||||
case IrInstructionIdBinOp:
|
|
||||||
case IrInstructionIdLoadVar:
|
|
||||||
case IrInstructionIdStoreVar:
|
|
||||||
case IrInstructionIdCall:
|
|
||||||
case IrInstructionIdBuiltinCall:
|
|
||||||
zig_panic("TODO print more IR instructions");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue