| ... | @@ -197,6 +197,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { | ... | @@ -197,6 +197,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { |
| 197 | return IrInstructionIdSliceType; | 197 | return IrInstructionIdSliceType; |
| 198 | } | 198 | } |
| 199 | | 199 | |
| | 200 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { |
| | 201 | return IrInstructionIdAsm; |
| | 202 | } |
| | 203 | |
| 200 | template<typename T> | 204 | template<typename T> |
| 201 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { | 205 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { |
| 202 | T *special_instruction = allocate<T>(1); | 206 | T *special_instruction = allocate<T>(1); |
| ... | @@ -796,6 +800,38 @@ static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node, | ... | @@ -796,6 +800,38 @@ static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node, |
| 796 | return &instruction->base; | 800 | return &instruction->base; |
| 797 | } | 801 | } |
| 798 | | 802 | |
| | 803 | static IrInstruction *ir_build_asm(IrBuilder *irb, AstNode *source_node, IrInstruction **input_list, |
| | 804 | IrInstruction **output_types, size_t return_count, bool has_side_effects) |
| | 805 | { |
| | 806 | IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, source_node); |
| | 807 | instruction->input_list = input_list; |
| | 808 | instruction->output_types = output_types; |
| | 809 | instruction->return_count = return_count; |
| | 810 | instruction->has_side_effects = has_side_effects; |
| | 811 | |
| | 812 | assert(source_node->type == NodeTypeAsmExpr); |
| | 813 | for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { |
| | 814 | IrInstruction *output_type = output_types[i]; |
| | 815 | if (output_type) ir_ref_instruction(output_type); |
| | 816 | } |
| | 817 | |
| | 818 | for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { |
| | 819 | IrInstruction *input_value = input_list[i]; |
| | 820 | ir_ref_instruction(input_value); |
| | 821 | } |
| | 822 | |
| | 823 | return &instruction->base; |
| | 824 | } |
| | 825 | |
| | 826 | static IrInstruction *ir_build_asm_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction **input_list, |
| | 827 | IrInstruction **output_types, size_t return_count, bool has_side_effects) |
| | 828 | { |
| | 829 | IrInstruction *new_instruction = ir_build_asm(irb, old_instruction->source_node, input_list, output_types, |
| | 830 | return_count, has_side_effects); |
| | 831 | ir_link_new_instruction(new_instruction, old_instruction); |
| | 832 | return new_instruction; |
| | 833 | } |
| | 834 | |
| 799 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, | 835 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, |
| 800 | bool gen_error_defers, bool gen_maybe_defers) | 836 | bool gen_error_defers, bool gen_maybe_defers) |
| 801 | { | 837 | { |
| ... | @@ -1683,6 +1719,56 @@ static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, AstNode *node) { | ... | @@ -1683,6 +1719,56 @@ static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, AstNode *node) { |
| 1683 | return ir_build_const_undefined(irb, node); | 1719 | return ir_build_const_undefined(irb, node); |
| 1684 | } | 1720 | } |
| 1685 | | 1721 | |
| | 1722 | static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) { |
| | 1723 | assert(node->type == NodeTypeAsmExpr); |
| | 1724 | |
| | 1725 | IrInstruction **input_list = allocate<IrInstruction *>(node->data.asm_expr.input_list.length); |
| | 1726 | IrInstruction **output_types = allocate<IrInstruction *>(node->data.asm_expr.output_list.length); |
| | 1727 | size_t return_count = 0; |
| | 1728 | bool is_volatile = node->data.asm_expr.is_volatile; |
| | 1729 | if (!is_volatile && node->data.asm_expr.output_list.length == 0) { |
| | 1730 | add_node_error(irb->codegen, node, |
| | 1731 | buf_sprintf("assembly expression with no output must be marked volatile")); |
| | 1732 | return irb->codegen->invalid_instruction; |
| | 1733 | } |
| | 1734 | for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1) { |
| | 1735 | AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); |
| | 1736 | if (asm_output->return_type) { |
| | 1737 | return_count += 1; |
| | 1738 | |
| | 1739 | IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->block_context); |
| | 1740 | if (return_type == irb->codegen->invalid_instruction) |
| | 1741 | return irb->codegen->invalid_instruction; |
| | 1742 | if (return_count > 1) { |
| | 1743 | add_node_error(irb->codegen, node, |
| | 1744 | buf_sprintf("inline assembly allows up to one output value")); |
| | 1745 | return irb->codegen->invalid_instruction; |
| | 1746 | } |
| | 1747 | output_types[i] = return_type; |
| | 1748 | } else { |
| | 1749 | Buf *variable_name = asm_output->variable_name; |
| | 1750 | VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name); |
| | 1751 | if (var) { |
| | 1752 | asm_output->variable = var; |
| | 1753 | } else { |
| | 1754 | add_node_error(irb->codegen, node, |
| | 1755 | buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); |
| | 1756 | return irb->codegen->invalid_instruction; |
| | 1757 | } |
| | 1758 | } |
| | 1759 | } |
| | 1760 | for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { |
| | 1761 | AsmInput *asm_input = node->data.asm_expr.input_list.at(i); |
| | 1762 | IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->block_context); |
| | 1763 | if (input_value == irb->codegen->invalid_instruction) |
| | 1764 | return irb->codegen->invalid_instruction; |
| | 1765 | |
| | 1766 | input_list[i] = input_value; |
| | 1767 | } |
| | 1768 | |
| | 1769 | return ir_build_asm(irb, node, input_list, output_types, return_count, is_volatile); |
| | 1770 | } |
| | 1771 | |
| 1686 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 1772 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context, |
| 1687 | LValPurpose lval) | 1773 | LValPurpose lval) |
| 1688 | { | 1774 | { |
| ... | @@ -1728,11 +1814,12 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -1728,11 +1814,12 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 1728 | return ir_gen_string_literal(irb, node); | 1814 | return ir_gen_string_literal(irb, node); |
| 1729 | case NodeTypeUndefinedLiteral: | 1815 | case NodeTypeUndefinedLiteral: |
| 1730 | return ir_gen_undefined_literal(irb, node); | 1816 | return ir_gen_undefined_literal(irb, node); |
| | 1817 | case NodeTypeAsmExpr: |
| | 1818 | return ir_gen_asm_expr(irb, node); |
| 1731 | case NodeTypeUnwrapErrorExpr: | 1819 | case NodeTypeUnwrapErrorExpr: |
| 1732 | case NodeTypeDefer: | 1820 | case NodeTypeDefer: |
| 1733 | case NodeTypeSliceExpr: | 1821 | case NodeTypeSliceExpr: |
| 1734 | case NodeTypeIfVarExpr: | 1822 | case NodeTypeIfVarExpr: |
| 1735 | case NodeTypeAsmExpr: | | |
| 1736 | case NodeTypeGoto: | 1823 | case NodeTypeGoto: |
| 1737 | case NodeTypeBreak: | 1824 | case NodeTypeBreak: |
| 1738 | case NodeTypeContinue: | 1825 | case NodeTypeContinue: |
| ... | @@ -3865,6 +3952,30 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -3865,6 +3952,30 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 3865 | zig_unreachable(); | 3952 | zig_unreachable(); |
| 3866 | } | 3953 | } |
| 3867 | | 3954 | |
| | 3955 | static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { |
| | 3956 | assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); |
| | 3957 | mark_impure_fn(ira->codegen, asm_instruction->base.source_node->block_context, |
| | 3958 | asm_instruction->base.source_node); |
| | 3959 | |
| | 3960 | // TODO validate the output types and variable types |
| | 3961 | |
| | 3962 | AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; |
| | 3963 | |
| | 3964 | TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void; |
| | 3965 | for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { |
| | 3966 | AsmOutput *asm_output = asm_expr->output_list.at(i); |
| | 3967 | if (asm_output->return_type) { |
| | 3968 | return_type = ir_resolve_type(ira, asm_instruction->output_types[i]); |
| | 3969 | if (return_type->id == TypeTableEntryIdInvalid) |
| | 3970 | return ira->codegen->builtin_types.entry_invalid; |
| | 3971 | } |
| | 3972 | } |
| | 3973 | |
| | 3974 | ir_build_asm_from(&ira->new_irb, &asm_instruction->base, asm_instruction->input_list, |
| | 3975 | asm_instruction->output_types, asm_instruction->return_count, asm_instruction->has_side_effects); |
| | 3976 | return return_type; |
| | 3977 | } |
| | 3978 | |
| 3868 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 3979 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 3869 | switch (instruction->id) { | 3980 | switch (instruction->id) { |
| 3870 | case IrInstructionIdInvalid: | 3981 | case IrInstructionIdInvalid: |
| ... | @@ -3911,6 +4022,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -3911,6 +4022,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 3911 | return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); | 4022 | return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); |
| 3912 | case IrInstructionIdSliceType: | 4023 | case IrInstructionIdSliceType: |
| 3913 | return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); | 4024 | return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); |
| | 4025 | case IrInstructionIdAsm: |
| | 4026 | return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); |
| 3914 | case IrInstructionIdSwitchBr: | 4027 | case IrInstructionIdSwitchBr: |
| 3915 | case IrInstructionIdCast: | 4028 | case IrInstructionIdCast: |
| 3916 | case IrInstructionIdContainerInitList: | 4029 | case IrInstructionIdContainerInitList: |
| ... | @@ -4020,6 +4133,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -4020,6 +4133,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 4020 | case IrInstructionIdArrayType: | 4133 | case IrInstructionIdArrayType: |
| 4021 | case IrInstructionIdSliceType: | 4134 | case IrInstructionIdSliceType: |
| 4022 | return false; | 4135 | return false; |
| | 4136 | case IrInstructionIdAsm: |
| | 4137 | { |
| | 4138 | IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; |
| | 4139 | return asm_instruction->has_side_effects; |
| | 4140 | } |
| 4023 | } | 4141 | } |
| 4024 | zig_unreachable(); | 4142 | zig_unreachable(); |
| 4025 | } | 4143 | } |
| ... | @@ -7135,44 +7253,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7135,44 +7253,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7135 | // return return_type; | 7253 | // return return_type; |
| 7136 | //} | 7254 | //} |
| 7137 | // | 7255 | // |
| 7138 | //static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 7139 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 7140 | //{ | | |
| 7141 | // mark_impure_fn(g, context, node); | | |
| 7142 | // | | |
| 7143 | // node->data.asm_expr.return_count = 0; | | |
| 7144 | // TypeTableEntry *return_type = g->builtin_types.entry_void; | | |
| 7145 | // for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1) { | | |
| 7146 | // AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); | | |
| 7147 | // if (asm_output->return_type) { | | |
| 7148 | // node->data.asm_expr.return_count += 1; | | |
| 7149 | // return_type = analyze_type_expr(g, import, context, asm_output->return_type); | | |
| 7150 | // if (node->data.asm_expr.return_count > 1) { | | |
| 7151 | // add_node_error(g, node, | | |
| 7152 | // buf_sprintf("inline assembly allows up to one output value")); | | |
| 7153 | // break; | | |
| 7154 | // } | | |
| 7155 | // } else { | | |
| 7156 | // Buf *variable_name = asm_output->variable_name; | | |
| 7157 | // VariableTableEntry *var = find_variable(g, context, variable_name); | | |
| 7158 | // if (var) { | | |
| 7159 | // asm_output->variable = var; | | |
| 7160 | // return var->type; | | |
| 7161 | // } else { | | |
| 7162 | // add_node_error(g, node, | | |
| 7163 | // buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); | | |
| 7164 | // return g->builtin_types.entry_invalid; | | |
| 7165 | // } | | |
| 7166 | // } | | |
| 7167 | // } | | |
| 7168 | // for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { | | |
| 7169 | // AsmInput *asm_input = node->data.asm_expr.input_list.at(i); | | |
| 7170 | // analyze_expression(g, import, context, nullptr, asm_input->expr); | | |
| 7171 | // } | | |
| 7172 | // | | |
| 7173 | // return return_type; | | |
| 7174 | //} | | |
| 7175 | // | | |
| 7176 | //static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | 7256 | //static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 7177 | // BlockContext *context, AstNode *node, Buf *err_name) | 7257 | // BlockContext *context, AstNode *node, Buf *err_name) |
| 7178 | //{ | 7258 | //{ |
| ... | @@ -7274,49 +7354,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7274,49 +7354,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7274 | // return var->type; | 7354 | // return var->type; |
| 7275 | //} | 7355 | //} |
| 7276 | // | 7356 | // |
| 7277 | //static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *import, | | |
| 7278 | // BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) | | |
| 7279 | //{ | | |
| 7280 | // assert(node->type == NodeTypeNullLiteral); | | |
| 7281 | // | | |
| 7282 | // ConstExprValue *const_val = &get_resolved_expr(node)->const_val; | | |
| 7283 | // const_val->ok = true; | | |
| 7284 | // | | |
| 7285 | // return g->builtin_types.entry_null; | | |
| 7286 | //} | | |
| 7287 | // | | |
| 7288 | //static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 7289 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 7290 | //{ | | |
| 7291 | // assert(node->type == NodeTypeUndefinedLiteral); | | |
| 7292 | // | | |
| 7293 | // Expr *expr = get_resolved_expr(node); | | |
| 7294 | // ConstExprValue *const_val = &expr->const_val; | | |
| 7295 | // | | |
| 7296 | // const_val->ok = true; | | |
| 7297 | // const_val->special = ConstValSpecialUndef; | | |
| 7298 | // | | |
| 7299 | // return expected_type ? expected_type : g->builtin_types.entry_undef; | | |
| 7300 | //} | | |
| 7301 | // | | |
| 7302 | //static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 7303 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 7304 | //{ | | |
| 7305 | // Expr *expr = get_resolved_expr(node); | | |
| 7306 | // ConstExprValue *const_val = &expr->const_val; | | |
| 7307 | // | | |
| 7308 | // const_val->ok = true; | | |
| 7309 | // const_val->special = ConstValSpecialZeroes; | | |
| 7310 | // | | |
| 7311 | // return expected_type ? expected_type : g->builtin_types.entry_undef; | | |
| 7312 | //} | | |
| 7313 | // | | |
| 7314 | //static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, | | |
| 7315 | // BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) | | |
| 7316 | //{ | | |
| 7317 | // return resolve_expr_const_val_as_bignum(g, node, expected_type, node->data.number_literal.bignum, false); | | |
| 7318 | //} | | |
| 7319 | // | | |
| 7320 | //static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 7357 | //static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 7321 | // TypeTableEntry *expected_type, AstNode *node) | 7358 | // TypeTableEntry *expected_type, AstNode *node) |
| 7322 | //{ | 7359 | //{ |
| ... | @@ -8656,111 +8693,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -8656,111 +8693,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 8656 | // } | 8693 | // } |
| 8657 | //} | 8694 | //} |
| 8658 | // | 8695 | // |
| 8659 | //static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { | | |
| 8660 | // assert(node->type == NodeTypeAsmExpr); | | |
| 8661 | // | | |
| 8662 | // AstNodeAsmExpr *asm_expr = &node->data.asm_expr; | | |
| 8663 | // | | |
| 8664 | // Buf *src_template = asm_expr->asm_template; | | |
| 8665 | // | | |
| 8666 | // Buf llvm_template = BUF_INIT; | | |
| 8667 | // buf_resize(&llvm_template, 0); | | |
| 8668 | // | | |
| 8669 | // for (size_t token_i = 0; token_i < asm_expr->token_list.length; token_i += 1) { | | |
| 8670 | // AsmToken *asm_token = &asm_expr->token_list.at(token_i); | | |
| 8671 | // switch (asm_token->id) { | | |
| 8672 | // case AsmTokenIdTemplate: | | |
| 8673 | // for (size_t offset = asm_token->start; offset < asm_token->end; offset += 1) { | | |
| 8674 | // uint8_t c = *((uint8_t*)(buf_ptr(src_template) + offset)); | | |
| 8675 | // if (c == '$') { | | |
| 8676 | // buf_append_str(&llvm_template, "$$"); | | |
| 8677 | // } else { | | |
| 8678 | // buf_append_char(&llvm_template, c); | | |
| 8679 | // } | | |
| 8680 | // } | | |
| 8681 | // break; | | |
| 8682 | // case AsmTokenIdPercent: | | |
| 8683 | // buf_append_char(&llvm_template, '%'); | | |
| 8684 | // break; | | |
| 8685 | // case AsmTokenIdVar: | | |
| 8686 | // size_t index = find_asm_index(g, node, asm_token); | | |
| 8687 | // assert(index < SIZE_MAX); | | |
| 8688 | // buf_appendf(&llvm_template, "$%zu", index); | | |
| 8689 | // break; | | |
| 8690 | // } | | |
| 8691 | // } | | |
| 8692 | // | | |
| 8693 | // Buf constraint_buf = BUF_INIT; | | |
| 8694 | // buf_resize(&constraint_buf, 0); | | |
| 8695 | // | | |
| 8696 | // assert(asm_expr->return_count == 0 || asm_expr->return_count == 1); | | |
| 8697 | // | | |
| 8698 | // size_t total_constraint_count = asm_expr->output_list.length + | | |
| 8699 | // asm_expr->input_list.length + | | |
| 8700 | // asm_expr->clobber_list.length; | | |
| 8701 | // size_t input_and_output_count = asm_expr->output_list.length + | | |
| 8702 | // asm_expr->input_list.length - | | |
| 8703 | // asm_expr->return_count; | | |
| 8704 | // size_t total_index = 0; | | |
| 8705 | // size_t param_index = 0; | | |
| 8706 | // LLVMTypeRef *param_types = allocate<LLVMTypeRef>(input_and_output_count); | | |
| 8707 | // LLVMValueRef *param_values = allocate<LLVMValueRef>(input_and_output_count); | | |
| 8708 | // for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) { | | |
| 8709 | // AsmOutput *asm_output = asm_expr->output_list.at(i); | | |
| 8710 | // bool is_return = (asm_output->return_type != nullptr); | | |
| 8711 | // assert(*buf_ptr(asm_output->constraint) == '='); | | |
| 8712 | // if (is_return) { | | |
| 8713 | // buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1); | | |
| 8714 | // } else { | | |
| 8715 | // buf_appendf(&constraint_buf, "=*%s", buf_ptr(asm_output->constraint) + 1); | | |
| 8716 | // } | | |
| 8717 | // if (total_index + 1 < total_constraint_count) { | | |
| 8718 | // buf_append_char(&constraint_buf, ','); | | |
| 8719 | // } | | |
| 8720 | // | | |
| 8721 | // if (!is_return) { | | |
| 8722 | // VariableTableEntry *variable = asm_output->variable; | | |
| 8723 | // assert(variable); | | |
| 8724 | // param_types[param_index] = LLVMTypeOf(variable->value_ref); | | |
| 8725 | // param_values[param_index] = variable->value_ref; | | |
| 8726 | // param_index += 1; | | |
| 8727 | // } | | |
| 8728 | // } | | |
| 8729 | // for (size_t i = 0; i < asm_expr->input_list.length; i += 1, total_index += 1, param_index += 1) { | | |
| 8730 | // AsmInput *asm_input = asm_expr->input_list.at(i); | | |
| 8731 | // buf_append_buf(&constraint_buf, asm_input->constraint); | | |
| 8732 | // if (total_index + 1 < total_constraint_count) { | | |
| 8733 | // buf_append_char(&constraint_buf, ','); | | |
| 8734 | // } | | |
| 8735 | // | | |
| 8736 | // TypeTableEntry *expr_type = get_expr_type(asm_input->expr); | | |
| 8737 | // param_types[param_index] = expr_type->type_ref; | | |
| 8738 | // param_values[param_index] = gen_expr(g, asm_input->expr); | | |
| 8739 | // } | | |
| 8740 | // for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { | | |
| 8741 | // Buf *clobber_buf = asm_expr->clobber_list.at(i); | | |
| 8742 | // buf_appendf(&constraint_buf, "~{%s}", buf_ptr(clobber_buf)); | | |
| 8743 | // if (total_index + 1 < total_constraint_count) { | | |
| 8744 | // buf_append_char(&constraint_buf, ','); | | |
| 8745 | // } | | |
| 8746 | // } | | |
| 8747 | // | | |
| 8748 | // LLVMTypeRef ret_type; | | |
| 8749 | // if (asm_expr->return_count == 0) { | | |
| 8750 | // ret_type = LLVMVoidType(); | | |
| 8751 | // } else { | | |
| 8752 | // ret_type = get_expr_type(node)->type_ref; | | |
| 8753 | // } | | |
| 8754 | // LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, input_and_output_count, false); | | |
| 8755 | // | | |
| 8756 | // bool is_volatile = asm_expr->is_volatile || (asm_expr->output_list.length == 0); | | |
| 8757 | // LLVMValueRef asm_fn = LLVMConstInlineAsm(function_type, buf_ptr(&llvm_template), | | |
| 8758 | // buf_ptr(&constraint_buf), is_volatile, false); | | |
| 8759 | // | | |
| 8760 | // set_debug_source_node(g, node); | | |
| 8761 | // return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); | | |
| 8762 | //} | | |
| 8763 | // | | |
| 8764 | //static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { | 8696 | //static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { |
| 8765 | // assert(node->type == NodeTypeContainerInitExpr); | 8697 | // assert(node->type == NodeTypeContainerInitExpr); |
| 8766 | // | 8698 | // |
| ... | @@ -9404,35 +9336,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -9404,35 +9336,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 9404 | // return result; | 9336 | // return result; |
| 9405 | //} | 9337 | //} |
| 9406 | // | 9338 | // |
| 9407 | //static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) { | | |
| 9408 | // const char *ptr = buf_ptr(node->data.asm_expr.asm_template) + tok->start + 2; | | |
| 9409 | // size_t len = tok->end - tok->start - 2; | | |
| 9410 | // size_t result = 0; | | |
| 9411 | // for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { | | |
| 9412 | // AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); | | |
| 9413 | // if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { | | |
| 9414 | // return result; | | |
| 9415 | // } | | |
| 9416 | // } | | |
| 9417 | // for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { | | |
| 9418 | // AsmInput *asm_input = node->data.asm_expr.input_list.at(i); | | |
| 9419 | // if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { | | |
| 9420 | // return result; | | |
| 9421 | // } | | |
| 9422 | // } | | |
| 9423 | // return SIZE_MAX; | | |
| 9424 | //} | | |
| 9425 | // | | |
| 9426 | //static LLVMValueRef gen_symbol(CodeGen *g, AstNode *node) { | | |
| 9427 | // assert(node->type == NodeTypeSymbol); | | |
| 9428 | // VariableTableEntry *variable = get_resolved_expr(node)->variable; | | |
| 9429 | // if (variable) { | | |
| 9430 | // return gen_variable(g, node, variable); | | |
| 9431 | // } | | |
| 9432 | // | | |
| 9433 | // zig_unreachable(); | | |
| 9434 | //} | | |
| 9435 | // | | |
| 9436 | //static LLVMValueRef gen_label(CodeGen *g, AstNode *node) { | 9339 | //static LLVMValueRef gen_label(CodeGen *g, AstNode *node) { |
| 9437 | // assert(node->type == NodeTypeLabel); | 9340 | // assert(node->type == NodeTypeLabel); |
| 9438 | // | 9341 | // |
| ... | @@ -9447,13 +9350,3 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -9447,13 +9350,3 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 9447 | // LLVMPositionBuilderAtEnd(g->builder, basic_block); | 9350 | // LLVMPositionBuilderAtEnd(g->builder, basic_block); |
| 9448 | // return nullptr; | 9351 | // return nullptr; |
| 9449 | //} | 9352 | //} |
| 9450 | // | | |
| 9451 | //static LLVMValueRef gen_variable(CodeGen *g, AstNode *source_node, VariableTableEntry *variable) { | | |
| 9452 | // if (!type_has_bits(variable->type)) { | | |
| 9453 | // return nullptr; | | |
| 9454 | // } else { | | |
| 9455 | // assert(variable->value_ref); | | |
| 9456 | // return get_handle_value(g, variable->value_ref, variable->type); | | |
| 9457 | // } | | |
| 9458 | //} | | |
| 9459 | // | | |