diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-01-30 23:36:52 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-01-30 23:39:25 -0500 |
| commit | 545064c1d9137a603e3e28aa066ce9e65a1ed4b6 (patch) | |
| tree | 1ab105ff0a2ec650c82aca4cb688b28ee54191b2 /src/codegen.cpp | |
| parent | 169a789b343e9070b4658de9c8bd96c6736c6edc (diff) | |
| download | zig-545064c1d9137a603e3e28aa066ce9e65a1ed4b6.tar.gz zig-545064c1d9137a603e3e28aa066ce9e65a1ed4b6.zip | |
introduce vector type for SIMD
See #903
* create with `@Vector(len, ElemType)`
* only wrapping addition is implemented
This feature is far from complete; this is only the beginning.
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 2f360735dd..e2576f5335 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1980,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ break; } - if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || + if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || ty->id == ZigTypeIdInt // TODO investigate if we need to change this ) { switch (fn_walk->id) { @@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } else { return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); } + } else if (type_entry->id == ZigTypeIdVector) { + ZigType *elem_type = type_entry->data.vector.elem_type; + if (elem_type->id == ZigTypeIdFloat) { + ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); + return LLVMBuildFAdd(g->builder, op1_value, op2_value, ""); + } else if (elem_type->id == ZigTypeIdPointer) { + zig_panic("TODO codegen for pointers in vectors"); + } else if (elem_type->id == ZigTypeIdInt) { + bool is_wrapping = (op_id == IrBinOpAddWrap); + if (is_wrapping) { + return LLVMBuildAdd(g->builder, op1_value, op2_value, ""); + } else if (want_runtime_safety) { + zig_panic("TODO runtime safety for vector integer addition"); + } else if (elem_type->data.integral.is_signed) { + return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, ""); + } else { + return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); + } + } else { + zig_unreachable(); + } } else { zig_unreachable(); } @@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdCUndef: case IrInstructionIdEmbedFile: case IrInstructionIdIntType: + case IrInstructionIdVectorType: case IrInstructionIdMemberCount: case IrInstructionIdMemberType: case IrInstructionIdMemberName: @@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con } case ZigTypeIdArray: zig_panic("TODO bit pack an array"); + case ZigTypeIdVector: + zig_panic("TODO bit pack a vector"); case ZigTypeIdUnion: zig_panic("TODO bit pack a union"); case ZigTypeIdStruct: @@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } } } + case ZigTypeIdVector: { + uint32_t len = type_entry->data.vector.len; + LLVMValueRef *values = allocate<LLVMValueRef>(len); + for (uint32_t i = 0; i < len; i += 1) { + values[i] = gen_const_val(g, &const_val->data.x_vector.elements[i], ""); + } + return LLVMConstVector(values, len); + } case ZigTypeIdUnion: { LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; @@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int + create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); @@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " ArgTuple: void,\n" " Opaque: void,\n" " Promise: Promise,\n" + " Vector: Vector,\n" "\n\n" " pub const Int = struct {\n" " is_signed: bool,\n" @@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " child: ?type,\n" " };\n" "\n" + " pub const Vector = struct {\n" + " len: u32,\n" + " child: type,\n" + " };\n" + "\n" " pub const Definition = struct {\n" " name: []const u8,\n" " is_pub: bool,\n" @@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e case ZigTypeIdArray: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); return; + case ZigTypeIdVector: + prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type); + return; case ZigTypeIdOptional: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); return; @@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu buf_appendf(out_buf, "%s", buf_ptr(child_buf)); return; } + case ZigTypeIdVector: + zig_panic("TODO implement get_c_type for vector types"); case ZigTypeIdErrorUnion: case ZigTypeIdErrorSet: case ZigTypeIdFn: @@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) { case ZigTypeIdOptional: case ZigTypeIdFn: case ZigTypeIdPromise: + case ZigTypeIdVector: zig_unreachable(); case ZigTypeIdEnum: if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { |
