aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-10-28 02:32:36 -0400
committerAndrew Kelley <superjoe30@gmail.com>2016-10-28 02:32:36 -0400
commit8e2804efa1d23696a476ab3f88c6b9852370cf8b (patch)
treeadd9fdc7bc0fd6b3ba1d0832a30efeaebc6a8451 /src/codegen.cpp
parent114049a22031be63da511ea53f4e655fc72a4578 (diff)
downloadzig-8e2804efa1d23696a476ab3f88c6b9852370cf8b.tar.gz
zig-8e2804efa1d23696a476ab3f88c6b9852370cf8b.zip
IR: ability to assign to an array at runtime
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 4f8af212d9..0a59e63dfa 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2857,18 +2857,45 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
}
static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) {
- return LLVMBuildLoad(g->builder, ir_llvm_value(g, instruction->ptr), "");
+ LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
+ return get_handle_value(g, ptr, instruction->base.type_entry);
}
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef value = ir_llvm_value(g, instruction->value);
+
+ assert(instruction->ptr->type_entry->id == TypeTableEntryIdPointer);
+ TypeTableEntry *op1_type = instruction->ptr->type_entry->data.pointer.child_type;
+ TypeTableEntry *op2_type = instruction->value->type_entry;
+
+ if (!type_has_bits(op1_type)) {
+ return nullptr;
+ }
+ if (handle_is_ptr(op1_type)) {
+ assert(op1_type == op2_type);
+ return gen_struct_memcpy(g, value, ptr, op1_type);
+ }
+
LLVMBuildStore(g->builder, value, ptr);
return nullptr;
}
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
- return instruction->var->value_ref;
+ VariableTableEntry *var = instruction->var;
+ if (type_has_bits(var->type)) {
+ assert(var->value_ref);
+ return get_handle_value(g, var->value_ref, var->type);
+ } else {
+ return nullptr;
+ }
+}
+
+static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
+ LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array_ptr);
+ LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index);
+ TypeTableEntry *array_type = instruction->array_ptr->type_entry;
+ return gen_array_elem_ptr(g, instruction->base.source_node, array_ptr, array_type, subscript_value);
}
static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
@@ -2942,6 +2969,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
case IrInstructionIdVarPtr:
return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
+ case IrInstructionIdElemPtr:
+ return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
case IrInstructionIdCall:
return ir_render_call(g, executable, (IrInstructionCall *)instruction);
case IrInstructionIdSwitchBr:
@@ -2950,7 +2979,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdContainerInitList:
case IrInstructionIdContainerInitFields:
case IrInstructionIdFieldPtr:
- case IrInstructionIdElemPtr:
zig_panic("TODO render more IR instructions to LLVM");
}
zig_unreachable();