diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 22e9720abb..8fe4191754 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1537,6 +1537,136 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa return LLVMBuildStructGEP(g->builder, struct_ptr, field->gen_index, ""); } +static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstructionAsm *instruction) { + zig_panic("TODO render asm"); +} +//static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) { +// const char *ptr = buf_ptr(node->data.asm_expr.asm_template) + tok->start + 2; +// size_t len = tok->end - tok->start - 2; +// size_t result = 0; +// for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { +// AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); +// if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { +// return result; +// } +// } +// for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { +// AsmInput *asm_input = node->data.asm_expr.input_list.at(i); +// if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { +// return result; +// } +// } +// return SIZE_MAX; +//} +// +//static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { +// assert(node->type == NodeTypeAsmExpr); +// +// AstNodeAsmExpr *asm_expr = &node->data.asm_expr; +// +// Buf *src_template = asm_expr->asm_template; +// +// Buf llvm_template = BUF_INIT; +// buf_resize(&llvm_template, 0); +// +// for (size_t token_i = 0; token_i < asm_expr->token_list.length; token_i += 1) { +// AsmToken *asm_token = &asm_expr->token_list.at(token_i); +// switch (asm_token->id) { +// case AsmTokenIdTemplate: +// for (size_t offset = asm_token->start; offset < asm_token->end; offset += 1) { +// uint8_t c = *((uint8_t*)(buf_ptr(src_template) + offset)); +// if (c == '$') { +// buf_append_str(&llvm_template, "$$"); +// } else { +// buf_append_char(&llvm_template, c); +// } +// } +// break; +// case AsmTokenIdPercent: +// buf_append_char(&llvm_template, '%'); +// break; +// case AsmTokenIdVar: +// size_t index = find_asm_index(g, node, asm_token); +// assert(index < SIZE_MAX); +// buf_appendf(&llvm_template, "$%zu", index); +// break; +// } +// } +// +// Buf constraint_buf = BUF_INIT; +// buf_resize(&constraint_buf, 0); +// +// assert(asm_expr->return_count == 0 || asm_expr->return_count == 1); +// +// size_t total_constraint_count = asm_expr->output_list.length + +// asm_expr->input_list.length + +// asm_expr->clobber_list.length; +// size_t input_and_output_count = asm_expr->output_list.length + +// asm_expr->input_list.length - +// asm_expr->return_count; +// size_t total_index = 0; +// size_t param_index = 0; +// LLVMTypeRef *param_types = allocate<LLVMTypeRef>(input_and_output_count); +// LLVMValueRef *param_values = allocate<LLVMValueRef>(input_and_output_count); +// for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) { +// AsmOutput *asm_output = asm_expr->output_list.at(i); +// bool is_return = (asm_output->return_type != nullptr); +// assert(*buf_ptr(asm_output->constraint) == '='); +// if (is_return) { +// buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1); +// } else { +// buf_appendf(&constraint_buf, "=*%s", buf_ptr(asm_output->constraint) + 1); +// } +// if (total_index + 1 < total_constraint_count) { +// buf_append_char(&constraint_buf, ','); +// } +// +// if (!is_return) { +// VariableTableEntry *variable = asm_output->variable; +// assert(variable); +// param_types[param_index] = LLVMTypeOf(variable->value_ref); +// param_values[param_index] = variable->value_ref; +// param_index += 1; +// } +// } +// for (size_t i = 0; i < asm_expr->input_list.length; i += 1, total_index += 1, param_index += 1) { +// AsmInput *asm_input = asm_expr->input_list.at(i); +// buf_append_buf(&constraint_buf, asm_input->constraint); +// if (total_index + 1 < total_constraint_count) { +// buf_append_char(&constraint_buf, ','); +// } +// +// TypeTableEntry *expr_type = get_expr_type(asm_input->expr); +// param_types[param_index] = expr_type->type_ref; +// param_values[param_index] = gen_expr(g, asm_input->expr); +// } +// for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { +// Buf *clobber_buf = asm_expr->clobber_list.at(i); +// buf_appendf(&constraint_buf, "~{%s}", buf_ptr(clobber_buf)); +// if (total_index + 1 < total_constraint_count) { +// buf_append_char(&constraint_buf, ','); +// } +// } +// +// LLVMTypeRef ret_type; +// if (asm_expr->return_count == 0) { +// ret_type = LLVMVoidType(); +// } else { +// ret_type = get_expr_type(node)->type_ref; +// } +// LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, input_and_output_count, false); +// +// bool is_volatile = asm_expr->is_volatile || (asm_expr->output_list.length == 0); +// LLVMValueRef asm_fn = LLVMConstInlineAsm(function_type, buf_ptr(&llvm_template), +// buf_ptr(&constraint_buf), is_volatile, false); +// +// set_debug_source_node(g, node); +// return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); +//} +// + + + static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { set_debug_source_node(g, instruction->source_node); @@ -1579,6 +1709,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_call(g, executable, (IrInstructionCall *)instruction); case IrInstructionIdStructFieldPtr: return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction); + case IrInstructionIdAsm: + return ir_render_asm(g, executable, (IrInstructionAsm *)instruction); case IrInstructionIdSwitchBr: case IrInstructionIdPhi: case IrInstructionIdContainerInitList: |
