| author | |
| committer | |
| log | 545064c1d9137a603e3e28aa066ce9e65a1ed4b6 |
| tree | 1ab105ff0a2ec650c82aca4cb688b28ee54191b2 |
| parent | 169a789b343e9070b4658de9c8bd96c6736c6edc |
| signature |
See #903
* create with `@Vector(len, ElemType)`
* only wrapping addition is implemented
This feature is far from complete; this is only the beginning.12 files changed, 419 insertions(+), 54 deletions(-)
doc/langref.html.in+34| ... | @@ -1531,6 +1531,29 @@ test "array initialization with function calls" { | ... | @@ -1531,6 +1531,29 @@ test "array initialization with function calls" { |
| 1531 | {#code_end#} | 1531 | {#code_end#} |
| 1532 | {#see_also|for|Slices#} | 1532 | {#see_also|for|Slices#} |
| 1533 | {#header_close#} | 1533 | {#header_close#} |
| 1534 | |||
| 1535 | {#header_open|Vectors#} | ||
| 1536 | <p> | ||
| 1537 | A vector is a group of {#link|Integers#}, {#link|Floats#}, or {#link|Pointers#} which are operated on | ||
| 1538 | in parallel using a single instruction ({#link|SIMD#}). Vector types are created with the builtin | ||
| 1539 | function {#link|@Vector#}. | ||
| 1540 | </p> | ||
| 1541 | <p> | ||
| 1542 | TODO talk about C ABI interop | ||
| 1543 | </p> | ||
| 1544 | {#header_open|SIMD#} | ||
| 1545 | <p> | ||
| 1546 | TODO Zig's SIMD abilities are just beginning to be fleshed out. Here are some talking points to update the | ||
| 1547 | docs with: | ||
| 1548 | * What kind of operations can you do? All the operations on integers and floats? What about mixing scalar and vector? | ||
| 1549 | * How to convert to/from vectors/arrays | ||
| 1550 | * How to access individual elements from vectors, how to loop over the elements | ||
| 1551 | * "shuffle" | ||
| 1552 | * Advice on writing high perf software, how to abstract the best way | ||
| 1553 | </p> | ||
| 1554 | {#header_close#} | ||
| 1555 | {#header_close#} | ||
| 1556 | |||
| 1534 | {#header_open|Pointers#} | 1557 | {#header_open|Pointers#} |
| 1535 | <p> | 1558 | <p> |
| 1536 | Zig has two kinds of pointers: | 1559 | Zig has two kinds of pointers: |
| ... | @@ -6607,6 +6630,17 @@ pub const TypeInfo = union(TypeId) { | ... | @@ -6607,6 +6630,17 @@ pub const TypeInfo = union(TypeId) { |
| 6607 | expression passed as an argument. The expression is evaluated. | 6630 | expression passed as an argument. The expression is evaluated. |
| 6608 | </p> | 6631 | </p> |
| 6609 | 6632 | ||
| 6633 | {#header_close#} | ||
| 6634 | |||
| 6635 | {#header_open|@Vector#} | ||
| 6636 | <pre>{#syntax#}@Vector(comptime len: u32, comptime ElemType: type) type{#endsyntax#}</pre> | ||
| 6637 | <p> | ||
| 6638 | This function returns a vector type for {#link|SIMD#}. | ||
| 6639 | </p> | ||
| 6640 | <p> | ||
| 6641 | {#syntax#}ElemType{#endsyntax#} must be an {#link|integer|Integers#}, a {#link|float|Floats#}, or a | ||
| 6642 | {#link|pointer|Pointers#}. | ||
| 6643 | </p> | ||
| 6610 | {#header_close#} | 6644 | {#header_close#} |
| 6611 | {#header_close#} | 6645 | {#header_close#} |
| 6612 | 6646 |
src-self-hosted/type.zig+16| ... | @@ -44,6 +44,7 @@ pub const Type = struct { | ... | @@ -44,6 +44,7 @@ pub const Type = struct { |
| 44 | Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp), | 44 | Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp), |
| 45 | Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp), | 45 | Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp), |
| 46 | Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp), | 46 | Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp), |
| 47 | Id.Vector => @fieldParentPtr(Vector, "base", base).destroy(comp), | ||
| 47 | } | 48 | } |
| 48 | } | 49 | } |
| 49 | 50 | ||
| ... | @@ -77,6 +78,7 @@ pub const Type = struct { | ... | @@ -77,6 +78,7 @@ pub const Type = struct { |
| 77 | Id.ArgTuple => unreachable, | 78 | Id.ArgTuple => unreachable, |
| 78 | Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context), | 79 | Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context), |
| 79 | Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(allocator, llvm_context), | 80 | Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(allocator, llvm_context), |
| 81 | Id.Vector => return @fieldParentPtr(Vector, "base", base).getLlvmType(allocator, llvm_context), | ||
| 80 | } | 82 | } |
| 81 | } | 83 | } |
| 82 | 84 | ||
| ... | @@ -103,6 +105,7 @@ pub const Type = struct { | ... | @@ -103,6 +105,7 @@ pub const Type = struct { |
| 103 | Id.Enum, | 105 | Id.Enum, |
| 104 | Id.Fn, | 106 | Id.Fn, |
| 105 | Id.Promise, | 107 | Id.Promise, |
| 108 | Id.Vector, | ||
| 106 | => return false, | 109 | => return false, |
| 107 | 110 | ||
| 108 | Id.Struct => @panic("TODO"), | 111 | Id.Struct => @panic("TODO"), |
| ... | @@ -135,6 +138,7 @@ pub const Type = struct { | ... | @@ -135,6 +138,7 @@ pub const Type = struct { |
| 135 | Id.Float, | 138 | Id.Float, |
| 136 | Id.Fn, | 139 | Id.Fn, |
| 137 | Id.Promise, | 140 | Id.Promise, |
| 141 | Id.Vector, | ||
| 138 | => return true, | 142 | => return true, |
| 139 | 143 | ||
| 140 | Id.Pointer => { | 144 | Id.Pointer => { |
| ... | @@ -902,6 +906,18 @@ pub const Type = struct { | ... | @@ -902,6 +906,18 @@ pub const Type = struct { |
| 902 | } | 906 | } |
| 903 | }; | 907 | }; |
| 904 | 908 | ||
| 909 | pub const Vector = struct { | ||
| 910 | base: Type, | ||
| 911 | |||
| 912 | pub fn destroy(self: *Vector, comp: *Compilation) void { | ||
| 913 | comp.gpa().destroy(self); | ||
| 914 | } | ||
| 915 | |||
| 916 | pub fn getLlvmType(self: *Vector, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef { | ||
| 917 | @panic("TODO"); | ||
| 918 | } | ||
| 919 | }; | ||
| 920 | |||
| 905 | pub const ComptimeFloat = struct { | 921 | pub const ComptimeFloat = struct { |
| 906 | base: Type, | 922 | base: Type, |
| 907 | 923 |
src/all_types.hpp+26| ... | @@ -252,6 +252,10 @@ struct ConstArgTuple { | ... | @@ -252,6 +252,10 @@ struct ConstArgTuple { |
| 252 | size_t end_index; | 252 | size_t end_index; |
| 253 | }; | 253 | }; |
| 254 | 254 | ||
| 255 | struct ConstVector { | ||
| 256 | ConstExprValue *elements; | ||
| 257 | }; | ||
| 258 | |||
| 255 | enum ConstValSpecial { | 259 | enum ConstValSpecial { |
| 256 | ConstValSpecialRuntime, | 260 | ConstValSpecialRuntime, |
| 257 | ConstValSpecialStatic, | 261 | ConstValSpecialStatic, |
| ... | @@ -318,6 +322,7 @@ struct ConstExprValue { | ... | @@ -318,6 +322,7 @@ struct ConstExprValue { |
| 318 | ConstPtrValue x_ptr; | 322 | ConstPtrValue x_ptr; |
| 319 | ImportTableEntry *x_import; | 323 | ImportTableEntry *x_import; |
| 320 | ConstArgTuple x_arg_tuple; | 324 | ConstArgTuple x_arg_tuple; |
| 325 | ConstVector x_vector; | ||
| 321 | 326 | ||
| 322 | // populated if special == ConstValSpecialRuntime | 327 | // populated if special == ConstValSpecialRuntime |
| 323 | RuntimeHintErrorUnion rh_error_union; | 328 | RuntimeHintErrorUnion rh_error_union; |
| ... | @@ -1210,6 +1215,12 @@ struct ZigTypePromise { | ... | @@ -1210,6 +1215,12 @@ struct ZigTypePromise { |
| 1210 | ZigType *result_type; | 1215 | ZigType *result_type; |
| 1211 | }; | 1216 | }; |
| 1212 | 1217 | ||
| 1218 | struct ZigTypeVector { | ||
| 1219 | // The type must be a pointer, integer, or float | ||
| 1220 | ZigType *elem_type; | ||
| 1221 | uint32_t len; | ||
| 1222 | }; | ||
| 1223 | |||
| 1213 | enum ZigTypeId { | 1224 | enum ZigTypeId { |
| 1214 | ZigTypeIdInvalid, | 1225 | ZigTypeIdInvalid, |
| 1215 | ZigTypeIdMetaType, | 1226 | ZigTypeIdMetaType, |
| ... | @@ -1236,6 +1247,7 @@ enum ZigTypeId { | ... | @@ -1236,6 +1247,7 @@ enum ZigTypeId { |
| 1236 | ZigTypeIdArgTuple, | 1247 | ZigTypeIdArgTuple, |
| 1237 | ZigTypeIdOpaque, | 1248 | ZigTypeIdOpaque, |
| 1238 | ZigTypeIdPromise, | 1249 | ZigTypeIdPromise, |
| 1250 | ZigTypeIdVector, | ||
| 1239 | }; | 1251 | }; |
| 1240 | 1252 | ||
| 1241 | struct ZigType { | 1253 | struct ZigType { |
| ... | @@ -1262,6 +1274,7 @@ struct ZigType { | ... | @@ -1262,6 +1274,7 @@ struct ZigType { |
| 1262 | ZigTypeFn fn; | 1274 | ZigTypeFn fn; |
| 1263 | ZigTypeBoundFn bound_fn; | 1275 | ZigTypeBoundFn bound_fn; |
| 1264 | ZigTypePromise promise; | 1276 | ZigTypePromise promise; |
| 1277 | ZigTypeVector vector; | ||
| 1265 | } data; | 1278 | } data; |
| 1266 | 1279 | ||
| 1267 | // use these fields to make sure we don't duplicate type table entries for the same type | 1280 | // use these fields to make sure we don't duplicate type table entries for the same type |
| ... | @@ -1415,6 +1428,7 @@ enum BuiltinFnId { | ... | @@ -1415,6 +1428,7 @@ enum BuiltinFnId { |
| 1415 | BuiltinFnIdEnumToInt, | 1428 | BuiltinFnIdEnumToInt, |
| 1416 | BuiltinFnIdIntToEnum, | 1429 | BuiltinFnIdIntToEnum, |
| 1417 | BuiltinFnIdIntType, | 1430 | BuiltinFnIdIntType, |
| 1431 | BuiltinFnIdVectorType, | ||
| 1418 | BuiltinFnIdSetCold, | 1432 | BuiltinFnIdSetCold, |
| 1419 | BuiltinFnIdSetRuntimeSafety, | 1433 | BuiltinFnIdSetRuntimeSafety, |
| 1420 | BuiltinFnIdSetFloatMode, | 1434 | BuiltinFnIdSetFloatMode, |
| ... | @@ -1505,6 +1519,10 @@ struct TypeId { | ... | @@ -1505,6 +1519,10 @@ struct TypeId { |
| 1505 | ZigType *err_set_type; | 1519 | ZigType *err_set_type; |
| 1506 | ZigType *payload_type; | 1520 | ZigType *payload_type; |
| 1507 | } error_union; | 1521 | } error_union; |
| 1522 | struct { | ||
| 1523 | ZigType *elem_type; | ||
| 1524 | uint32_t len; | ||
| 1525 | } vector; | ||
| 1508 | } data; | 1526 | } data; |
| 1509 | }; | 1527 | }; |
| 1510 | 1528 | ||
| ... | @@ -2139,6 +2157,7 @@ enum IrInstructionId { | ... | @@ -2139,6 +2157,7 @@ enum IrInstructionId { |
| 2139 | IrInstructionIdFloatToInt, | 2157 | IrInstructionIdFloatToInt, |
| 2140 | IrInstructionIdBoolToInt, | 2158 | IrInstructionIdBoolToInt, |
| 2141 | IrInstructionIdIntType, | 2159 | IrInstructionIdIntType, |
| 2160 | IrInstructionIdVectorType, | ||
| 2142 | IrInstructionIdBoolNot, | 2161 | IrInstructionIdBoolNot, |
| 2143 | IrInstructionIdMemset, | 2162 | IrInstructionIdMemset, |
| 2144 | IrInstructionIdMemcpy, | 2163 | IrInstructionIdMemcpy, |
| ... | @@ -2807,6 +2826,13 @@ struct IrInstructionIntType { | ... | @@ -2807,6 +2826,13 @@ struct IrInstructionIntType { |
| 2807 | IrInstruction *bit_count; | 2826 | IrInstruction *bit_count; |
| 2808 | }; | 2827 | }; |
| 2809 | 2828 | ||
| 2829 | struct IrInstructionVectorType { | ||
| 2830 | IrInstruction base; | ||
| 2831 | |||
| 2832 | IrInstruction *len; | ||
| 2833 | IrInstruction *elem_type; | ||
| 2834 | }; | ||
| 2835 | |||
| 2810 | struct IrInstructionBoolNot { | 2836 | struct IrInstructionBoolNot { |
| 2811 | IrInstruction base; | 2837 | IrInstruction base; |
| 2812 | 2838 |
src/analyze.cpp+85-6| ... | @@ -250,6 +250,7 @@ AstNode *type_decl_node(ZigType *type_entry) { | ... | @@ -250,6 +250,7 @@ AstNode *type_decl_node(ZigType *type_entry) { |
| 250 | case ZigTypeIdBoundFn: | 250 | case ZigTypeIdBoundFn: |
| 251 | case ZigTypeIdArgTuple: | 251 | case ZigTypeIdArgTuple: |
| 252 | case ZigTypeIdPromise: | 252 | case ZigTypeIdPromise: |
| 253 | case ZigTypeIdVector: | ||
| 253 | return nullptr; | 254 | return nullptr; |
| 254 | } | 255 | } |
| 255 | zig_unreachable(); | 256 | zig_unreachable(); |
| ... | @@ -311,6 +312,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { | ... | @@ -311,6 +312,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 311 | case ZigTypeIdBoundFn: | 312 | case ZigTypeIdBoundFn: |
| 312 | case ZigTypeIdArgTuple: | 313 | case ZigTypeIdArgTuple: |
| 313 | case ZigTypeIdPromise: | 314 | case ZigTypeIdPromise: |
| 315 | case ZigTypeIdVector: | ||
| 314 | return true; | 316 | return true; |
| 315 | } | 317 | } |
| 316 | zig_unreachable(); | 318 | zig_unreachable(); |
| ... | @@ -1055,11 +1057,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { | ... | @@ -1055,11 +1057,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { |
| 1055 | } | 1057 | } |
| 1056 | if (g->zig_target.arch.arch == ZigLLVM_x86_64) { | 1058 | if (g->zig_target.arch.arch == ZigLLVM_x86_64) { |
| 1057 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type); | 1059 | X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type); |
| 1058 | if (abi_class == X64CABIClass_MEMORY) { | 1060 | return abi_class == X64CABIClass_MEMORY; |
| 1059 | return true; | ||
| 1060 | } | ||
| 1061 | zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481", | ||
| 1062 | buf_ptr(&fn_type_id->return_type->name)); | ||
| 1063 | } else if (target_is_arm(&g->zig_target)) { | 1061 | } else if (target_is_arm(&g->zig_target)) { |
| 1064 | return type_size(g, fn_type_id->return_type) > 16; | 1062 | return type_size(g, fn_type_id->return_type) > 16; |
| 1065 | } | 1063 | } |
| ... | @@ -1424,6 +1422,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) { | ... | @@ -1424,6 +1422,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) { |
| 1424 | case ZigTypeIdPointer: | 1422 | case ZigTypeIdPointer: |
| 1425 | case ZigTypeIdArray: | 1423 | case ZigTypeIdArray: |
| 1426 | case ZigTypeIdFn: | 1424 | case ZigTypeIdFn: |
| 1425 | case ZigTypeIdVector: | ||
| 1427 | return true; | 1426 | return true; |
| 1428 | case ZigTypeIdStruct: | 1427 | case ZigTypeIdStruct: |
| 1429 | return type_entry->data.structure.layout == ContainerLayoutPacked; | 1428 | return type_entry->data.structure.layout == ContainerLayoutPacked; |
| ... | @@ -1472,6 +1471,8 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) { | ... | @@ -1472,6 +1471,8 @@ static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) { |
| 1472 | default: | 1471 | default: |
| 1473 | return false; | 1472 | return false; |
| 1474 | } | 1473 | } |
| 1474 | case ZigTypeIdVector: | ||
| 1475 | return type_allowed_in_extern(g, type_entry->data.vector.elem_type); | ||
| 1475 | case ZigTypeIdFloat: | 1476 | case ZigTypeIdFloat: |
| 1476 | return true; | 1477 | return true; |
| 1477 | case ZigTypeIdArray: | 1478 | case ZigTypeIdArray: |
| ... | @@ -1625,6 +1626,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc | ... | @@ -1625,6 +1626,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1625 | case ZigTypeIdUnion: | 1626 | case ZigTypeIdUnion: |
| 1626 | case ZigTypeIdFn: | 1627 | case ZigTypeIdFn: |
| 1627 | case ZigTypeIdPromise: | 1628 | case ZigTypeIdPromise: |
| 1629 | case ZigTypeIdVector: | ||
| 1628 | switch (type_requires_comptime(g, type_entry)) { | 1630 | switch (type_requires_comptime(g, type_entry)) { |
| 1629 | case ReqCompTimeNo: | 1631 | case ReqCompTimeNo: |
| 1630 | break; | 1632 | break; |
| ... | @@ -1720,6 +1722,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc | ... | @@ -1720,6 +1722,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1720 | case ZigTypeIdUnion: | 1722 | case ZigTypeIdUnion: |
| 1721 | case ZigTypeIdFn: | 1723 | case ZigTypeIdFn: |
| 1722 | case ZigTypeIdPromise: | 1724 | case ZigTypeIdPromise: |
| 1725 | case ZigTypeIdVector: | ||
| 1723 | switch (type_requires_comptime(g, fn_type_id.return_type)) { | 1726 | switch (type_requires_comptime(g, fn_type_id.return_type)) { |
| 1724 | case ReqCompTimeInvalid: | 1727 | case ReqCompTimeInvalid: |
| 1725 | return g->builtin_types.entry_invalid; | 1728 | return g->builtin_types.entry_invalid; |
| ... | @@ -3577,6 +3580,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry | ... | @@ -3577,6 +3580,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry |
| 3577 | case ZigTypeIdFn: | 3580 | case ZigTypeIdFn: |
| 3578 | case ZigTypeIdBoundFn: | 3581 | case ZigTypeIdBoundFn: |
| 3579 | case ZigTypeIdPromise: | 3582 | case ZigTypeIdPromise: |
| 3583 | case ZigTypeIdVector: | ||
| 3580 | return type_entry; | 3584 | return type_entry; |
| 3581 | } | 3585 | } |
| 3582 | zig_unreachable(); | 3586 | zig_unreachable(); |
| ... | @@ -3943,6 +3947,7 @@ static bool is_container(ZigType *type_entry) { | ... | @@ -3943,6 +3947,7 @@ static bool is_container(ZigType *type_entry) { |
| 3943 | case ZigTypeIdArgTuple: | 3947 | case ZigTypeIdArgTuple: |
| 3944 | case ZigTypeIdOpaque: | 3948 | case ZigTypeIdOpaque: |
| 3945 | case ZigTypeIdPromise: | 3949 | case ZigTypeIdPromise: |
| 3950 | case ZigTypeIdVector: | ||
| 3946 | return false; | 3951 | return false; |
| 3947 | } | 3952 | } |
| 3948 | zig_unreachable(); | 3953 | zig_unreachable(); |
| ... | @@ -4002,6 +4007,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { | ... | @@ -4002,6 +4007,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 4002 | case ZigTypeIdArgTuple: | 4007 | case ZigTypeIdArgTuple: |
| 4003 | case ZigTypeIdOpaque: | 4008 | case ZigTypeIdOpaque: |
| 4004 | case ZigTypeIdPromise: | 4009 | case ZigTypeIdPromise: |
| 4010 | case ZigTypeIdVector: | ||
| 4005 | zig_unreachable(); | 4011 | zig_unreachable(); |
| 4006 | } | 4012 | } |
| 4007 | } | 4013 | } |
| ... | @@ -4451,6 +4457,34 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { | ... | @@ -4451,6 +4457,34 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { |
| 4451 | return new_entry; | 4457 | return new_entry; |
| 4452 | } | 4458 | } |
| 4453 | 4459 | ||
| 4460 | ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) { | ||
| 4461 | TypeId type_id = {}; | ||
| 4462 | type_id.id = ZigTypeIdVector; | ||
| 4463 | type_id.data.vector.len = len; | ||
| 4464 | type_id.data.vector.elem_type = elem_type; | ||
| 4465 | |||
| 4466 | { | ||
| 4467 | auto entry = g->type_table.maybe_get(type_id); | ||
| 4468 | if (entry) | ||
| 4469 | return entry->value; | ||
| 4470 | } | ||
| 4471 | |||
| 4472 | ZigType *entry = new_type_table_entry(ZigTypeIdVector); | ||
| 4473 | entry->zero_bits = (len == 0) || !type_has_bits(elem_type); | ||
| 4474 | entry->type_ref = entry->zero_bits ? LLVMVoidType() : LLVMVectorType(elem_type->type_ref, len); | ||
| 4475 | entry->data.vector.len = len; | ||
| 4476 | entry->data.vector.elem_type = elem_type; | ||
| 4477 | |||
| 4478 | buf_resize(&entry->name, 0); | ||
| 4479 | buf_appendf(&entry->name, "@Vector(%u, %s)", len, buf_ptr(&elem_type->name)); | ||
| 4480 | |||
| 4481 | entry->di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, len, | ||
| 4482 | LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref), elem_type->di_type); | ||
| 4483 | |||
| 4484 | g->type_table.put(type_id, entry); | ||
| 4485 | return entry; | ||
| 4486 | } | ||
| 4487 | |||
| 4454 | ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) { | 4488 | ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) { |
| 4455 | return &g->builtin_types.entry_c_int[c_int_type]; | 4489 | return &g->builtin_types.entry_c_int[c_int_type]; |
| 4456 | } | 4490 | } |
| ... | @@ -4482,6 +4516,7 @@ bool handle_is_ptr(ZigType *type_entry) { | ... | @@ -4482,6 +4516,7 @@ bool handle_is_ptr(ZigType *type_entry) { |
| 4482 | case ZigTypeIdFn: | 4516 | case ZigTypeIdFn: |
| 4483 | case ZigTypeIdEnum: | 4517 | case ZigTypeIdEnum: |
| 4484 | case ZigTypeIdPromise: | 4518 | case ZigTypeIdPromise: |
| 4519 | case ZigTypeIdVector: | ||
| 4485 | return false; | 4520 | return false; |
| 4486 | case ZigTypeIdArray: | 4521 | case ZigTypeIdArray: |
| 4487 | case ZigTypeIdStruct: | 4522 | case ZigTypeIdStruct: |
| ... | @@ -4914,6 +4949,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) { | ... | @@ -4914,6 +4949,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) { |
| 4914 | return hash_const_val_error_set(const_val); | 4949 | return hash_const_val_error_set(const_val); |
| 4915 | case ZigTypeIdNamespace: | 4950 | case ZigTypeIdNamespace: |
| 4916 | return hash_ptr(const_val->data.x_import); | 4951 | return hash_ptr(const_val->data.x_import); |
| 4952 | case ZigTypeIdVector: | ||
| 4953 | // TODO better hashing algorithm | ||
| 4954 | return 3647867726; | ||
| 4917 | case ZigTypeIdBoundFn: | 4955 | case ZigTypeIdBoundFn: |
| 4918 | case ZigTypeIdInvalid: | 4956 | case ZigTypeIdInvalid: |
| 4919 | case ZigTypeIdUnreachable: | 4957 | case ZigTypeIdUnreachable: |
| ... | @@ -4966,6 +5004,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { | ... | @@ -4966,6 +5004,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { |
| 4966 | case ZigTypeIdBool: | 5004 | case ZigTypeIdBool: |
| 4967 | case ZigTypeIdUnreachable: | 5005 | case ZigTypeIdUnreachable: |
| 4968 | case ZigTypeIdInt: | 5006 | case ZigTypeIdInt: |
| 5007 | case ZigTypeIdVector: | ||
| 4969 | case ZigTypeIdFloat: | 5008 | case ZigTypeIdFloat: |
| 4970 | case ZigTypeIdComptimeFloat: | 5009 | case ZigTypeIdComptimeFloat: |
| 4971 | case ZigTypeIdComptimeInt: | 5010 | case ZigTypeIdComptimeInt: |
| ... | @@ -5049,6 +5088,7 @@ static bool return_type_is_cacheable(ZigType *return_type) { | ... | @@ -5049,6 +5088,7 @@ static bool return_type_is_cacheable(ZigType *return_type) { |
| 5049 | case ZigTypeIdErrorSet: | 5088 | case ZigTypeIdErrorSet: |
| 5050 | case ZigTypeIdEnum: | 5089 | case ZigTypeIdEnum: |
| 5051 | case ZigTypeIdPointer: | 5090 | case ZigTypeIdPointer: |
| 5091 | case ZigTypeIdVector: | ||
| 5052 | return true; | 5092 | return true; |
| 5053 | 5093 | ||
| 5054 | case ZigTypeIdArray: | 5094 | case ZigTypeIdArray: |
| ... | @@ -5201,6 +5241,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { | ... | @@ -5201,6 +5241,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { |
| 5201 | case ZigTypeIdErrorSet: | 5241 | case ZigTypeIdErrorSet: |
| 5202 | case ZigTypeIdEnum: | 5242 | case ZigTypeIdEnum: |
| 5203 | case ZigTypeIdInt: | 5243 | case ZigTypeIdInt: |
| 5244 | case ZigTypeIdVector: | ||
| 5204 | return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes; | 5245 | return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes; |
| 5205 | case ZigTypeIdPointer: | 5246 | case ZigTypeIdPointer: |
| 5206 | return type_has_one_possible_value(g, type_entry->data.pointer.child_type); | 5247 | return type_has_one_possible_value(g, type_entry->data.pointer.child_type); |
| ... | @@ -5251,6 +5292,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { | ... | @@ -5251,6 +5292,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { |
| 5251 | case ZigTypeIdErrorSet: | 5292 | case ZigTypeIdErrorSet: |
| 5252 | case ZigTypeIdBool: | 5293 | case ZigTypeIdBool: |
| 5253 | case ZigTypeIdInt: | 5294 | case ZigTypeIdInt: |
| 5295 | case ZigTypeIdVector: | ||
| 5254 | case ZigTypeIdFloat: | 5296 | case ZigTypeIdFloat: |
| 5255 | case ZigTypeIdVoid: | 5297 | case ZigTypeIdVoid: |
| 5256 | case ZigTypeIdUnreachable: | 5298 | case ZigTypeIdUnreachable: |
| ... | @@ -5777,7 +5819,7 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { | ... | @@ -5777,7 +5819,7 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { |
| 5777 | ConstExprValue *a_elems = a->data.x_array.data.s_none.elements; | 5819 | ConstExprValue *a_elems = a->data.x_array.data.s_none.elements; |
| 5778 | ConstExprValue *b_elems = b->data.x_array.data.s_none.elements; | 5820 | ConstExprValue *b_elems = b->data.x_array.data.s_none.elements; |
| 5779 | 5821 | ||
| 5780 | for (size_t i = 0; i < len; ++i) { | 5822 | for (size_t i = 0; i < len; i += 1) { |
| 5781 | if (!const_values_equal(g, &a_elems[i], &b_elems[i])) | 5823 | if (!const_values_equal(g, &a_elems[i], &b_elems[i])) |
| 5782 | return false; | 5824 | return false; |
| 5783 | } | 5825 | } |
| ... | @@ -5811,6 +5853,20 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { | ... | @@ -5811,6 +5853,20 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { |
| 5811 | case ZigTypeIdArgTuple: | 5853 | case ZigTypeIdArgTuple: |
| 5812 | return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index && | 5854 | return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index && |
| 5813 | a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index; | 5855 | a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index; |
| 5856 | case ZigTypeIdVector: { | ||
| 5857 | assert(a->type->data.vector.len == b->type->data.vector.len); | ||
| 5858 | |||
| 5859 | size_t len = a->type->data.vector.len; | ||
| 5860 | ConstExprValue *a_elems = a->data.x_vector.elements; | ||
| 5861 | ConstExprValue *b_elems = b->data.x_vector.elements; | ||
| 5862 | |||
| 5863 | for (size_t i = 0; i < len; i += 1) { | ||
| 5864 | if (!const_values_equal(g, &a_elems[i], &b_elems[i])) | ||
| 5865 | return false; | ||
| 5866 | } | ||
| 5867 | |||
| 5868 | return true; | ||
| 5869 | } | ||
| 5814 | case ZigTypeIdBoundFn: | 5870 | case ZigTypeIdBoundFn: |
| 5815 | case ZigTypeIdInvalid: | 5871 | case ZigTypeIdInvalid: |
| 5816 | case ZigTypeIdUnreachable: | 5872 | case ZigTypeIdUnreachable: |
| ... | @@ -6042,6 +6098,18 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { | ... | @@ -6042,6 +6098,18 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 6042 | } | 6098 | } |
| 6043 | } | 6099 | } |
| 6044 | zig_unreachable(); | 6100 | zig_unreachable(); |
| 6101 | case ZigTypeIdVector: { | ||
| 6102 | buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); | ||
| 6103 | uint64_t len = type_entry->data.vector.len; | ||
| 6104 | for (uint32_t i = 0; i < len; i += 1) { | ||
| 6105 | if (i != 0) | ||
| 6106 | buf_appendf(buf, ","); | ||
| 6107 | ConstExprValue *child_value = &const_val->data.x_vector.elements[i]; | ||
| 6108 | render_const_value(g, buf, child_value); | ||
| 6109 | } | ||
| 6110 | buf_appendf(buf, "}"); | ||
| 6111 | return; | ||
| 6112 | } | ||
| 6045 | case ZigTypeIdNull: | 6113 | case ZigTypeIdNull: |
| 6046 | { | 6114 | { |
| 6047 | buf_appendf(buf, "null"); | 6115 | buf_appendf(buf, "null"); |
| ... | @@ -6200,6 +6268,8 @@ uint32_t type_id_hash(TypeId x) { | ... | @@ -6200,6 +6268,8 @@ uint32_t type_id_hash(TypeId x) { |
| 6200 | case ZigTypeIdInt: | 6268 | case ZigTypeIdInt: |
| 6201 | return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) + | 6269 | return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) + |
| 6202 | (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557); | 6270 | (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557); |
| 6271 | case ZigTypeIdVector: | ||
| 6272 | return hash_ptr(x.data.vector.elem_type) * (x.data.vector.len * 526582681); | ||
| 6203 | } | 6273 | } |
| 6204 | zig_unreachable(); | 6274 | zig_unreachable(); |
| 6205 | } | 6275 | } |
| ... | @@ -6248,6 +6318,9 @@ bool type_id_eql(TypeId a, TypeId b) { | ... | @@ -6248,6 +6318,9 @@ bool type_id_eql(TypeId a, TypeId b) { |
| 6248 | case ZigTypeIdInt: | 6318 | case ZigTypeIdInt: |
| 6249 | return a.data.integer.is_signed == b.data.integer.is_signed && | 6319 | return a.data.integer.is_signed == b.data.integer.is_signed && |
| 6250 | a.data.integer.bit_count == b.data.integer.bit_count; | 6320 | a.data.integer.bit_count == b.data.integer.bit_count; |
| 6321 | case ZigTypeIdVector: | ||
| 6322 | return a.data.vector.elem_type == b.data.vector.elem_type && | ||
| 6323 | a.data.vector.len == b.data.vector.len; | ||
| 6251 | } | 6324 | } |
| 6252 | zig_unreachable(); | 6325 | zig_unreachable(); |
| 6253 | } | 6326 | } |
| ... | @@ -6382,6 +6455,7 @@ static const ZigTypeId all_type_ids[] = { | ... | @@ -6382,6 +6455,7 @@ static const ZigTypeId all_type_ids[] = { |
| 6382 | ZigTypeIdArgTuple, | 6455 | ZigTypeIdArgTuple, |
| 6383 | ZigTypeIdOpaque, | 6456 | ZigTypeIdOpaque, |
| 6384 | ZigTypeIdPromise, | 6457 | ZigTypeIdPromise, |
| 6458 | ZigTypeIdVector, | ||
| 6385 | }; | 6459 | }; |
| 6386 | 6460 | ||
| 6387 | ZigTypeId type_id_at_index(size_t index) { | 6461 | ZigTypeId type_id_at_index(size_t index) { |
| ... | @@ -6447,6 +6521,8 @@ size_t type_id_index(ZigType *entry) { | ... | @@ -6447,6 +6521,8 @@ size_t type_id_index(ZigType *entry) { |
| 6447 | return 22; | 6521 | return 22; |
| 6448 | case ZigTypeIdPromise: | 6522 | case ZigTypeIdPromise: |
| 6449 | return 23; | 6523 | return 23; |
| 6524 | case ZigTypeIdVector: | ||
| 6525 | return 24; | ||
| 6450 | } | 6526 | } |
| 6451 | zig_unreachable(); | 6527 | zig_unreachable(); |
| 6452 | } | 6528 | } |
| ... | @@ -6503,6 +6579,8 @@ const char *type_id_name(ZigTypeId id) { | ... | @@ -6503,6 +6579,8 @@ const char *type_id_name(ZigTypeId id) { |
| 6503 | return "Opaque"; | 6579 | return "Opaque"; |
| 6504 | case ZigTypeIdPromise: | 6580 | case ZigTypeIdPromise: |
| 6505 | return "Promise"; | 6581 | return "Promise"; |
| 6582 | case ZigTypeIdVector: | ||
| 6583 | return "Vector"; | ||
| 6506 | } | 6584 | } |
| 6507 | zig_unreachable(); | 6585 | zig_unreachable(); |
| 6508 | } | 6586 | } |
| ... | @@ -6658,6 +6736,7 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { | ... | @@ -6658,6 +6736,7 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { |
| 6658 | case ZigTypeIdBool: | 6736 | case ZigTypeIdBool: |
| 6659 | return X64CABIClass_INTEGER; | 6737 | return X64CABIClass_INTEGER; |
| 6660 | case ZigTypeIdFloat: | 6738 | case ZigTypeIdFloat: |
| 6739 | case ZigTypeIdVector: | ||
| 6661 | return X64CABIClass_SSE; | 6740 | return X64CABIClass_SSE; |
| 6662 | case ZigTypeIdStruct: { | 6741 | case ZigTypeIdStruct: { |
| 6663 | // "If the size of an object is larger than four eightbytes, or it contains unaligned | 6742 | // "If the size of an object is larger than four eightbytes, or it contains unaligned |
src/analyze.hpp+1| ... | @@ -20,6 +20,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons | ... | @@ -20,6 +20,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons |
| 20 | uint64_t type_size(CodeGen *g, ZigType *type_entry); | 20 | uint64_t type_size(CodeGen *g, ZigType *type_entry); |
| 21 | uint64_t type_size_bits(CodeGen *g, ZigType *type_entry); | 21 | uint64_t type_size_bits(CodeGen *g, ZigType *type_entry); |
| 22 | ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); | 22 | ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); |
| 23 | ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type); | ||
| 23 | ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type); | 24 | ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type); |
| 24 | ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type); | 25 | ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type); |
| 25 | ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); | 26 | ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); |
src/codegen.cpp+46-1| ... | @@ -1980,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ | ... | @@ -1980,7 +1980,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 1980 | break; | 1980 | break; |
| 1981 | } | 1981 | } |
| 1982 | 1982 | ||
| 1983 | if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || | 1983 | if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || |
| 1984 | ty->id == ZigTypeIdInt // TODO investigate if we need to change this | 1984 | ty->id == ZigTypeIdInt // TODO investigate if we need to change this |
| 1985 | ) { | 1985 | ) { |
| 1986 | switch (fn_walk->id) { | 1986 | switch (fn_walk->id) { |
| ... | @@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, | ... | @@ -2660,6 +2660,27 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, |
| 2660 | } else { | 2660 | } else { |
| 2661 | return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); | 2661 | return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); |
| 2662 | } | 2662 | } |
| 2663 | } else if (type_entry->id == ZigTypeIdVector) { | ||
| 2664 | ZigType *elem_type = type_entry->data.vector.elem_type; | ||
| 2665 | if (elem_type->id == ZigTypeIdFloat) { | ||
| 2666 | ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); | ||
| 2667 | return LLVMBuildFAdd(g->builder, op1_value, op2_value, ""); | ||
| 2668 | } else if (elem_type->id == ZigTypeIdPointer) { | ||
| 2669 | zig_panic("TODO codegen for pointers in vectors"); | ||
| 2670 | } else if (elem_type->id == ZigTypeIdInt) { | ||
| 2671 | bool is_wrapping = (op_id == IrBinOpAddWrap); | ||
| 2672 | if (is_wrapping) { | ||
| 2673 | return LLVMBuildAdd(g->builder, op1_value, op2_value, ""); | ||
| 2674 | } else if (want_runtime_safety) { | ||
| 2675 | zig_panic("TODO runtime safety for vector integer addition"); | ||
| 2676 | } else if (elem_type->data.integral.is_signed) { | ||
| 2677 | return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, ""); | ||
| 2678 | } else { | ||
| 2679 | return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); | ||
| 2680 | } | ||
| 2681 | } else { | ||
| 2682 | zig_unreachable(); | ||
| 2683 | } | ||
| 2663 | } else { | 2684 | } else { |
| 2664 | zig_unreachable(); | 2685 | zig_unreachable(); |
| 2665 | } | 2686 | } |
| ... | @@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -5211,6 +5232,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5211 | case IrInstructionIdCUndef: | 5232 | case IrInstructionIdCUndef: |
| 5212 | case IrInstructionIdEmbedFile: | 5233 | case IrInstructionIdEmbedFile: |
| 5213 | case IrInstructionIdIntType: | 5234 | case IrInstructionIdIntType: |
| 5235 | case IrInstructionIdVectorType: | ||
| 5214 | case IrInstructionIdMemberCount: | 5236 | case IrInstructionIdMemberCount: |
| 5215 | case IrInstructionIdMemberType: | 5237 | case IrInstructionIdMemberType: |
| 5216 | case IrInstructionIdMemberName: | 5238 | case IrInstructionIdMemberName: |
| ... | @@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con | ... | @@ -5620,6 +5642,8 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con |
| 5620 | } | 5642 | } |
| 5621 | case ZigTypeIdArray: | 5643 | case ZigTypeIdArray: |
| 5622 | zig_panic("TODO bit pack an array"); | 5644 | zig_panic("TODO bit pack an array"); |
| 5645 | case ZigTypeIdVector: | ||
| 5646 | zig_panic("TODO bit pack a vector"); | ||
| 5623 | case ZigTypeIdUnion: | 5647 | case ZigTypeIdUnion: |
| 5624 | zig_panic("TODO bit pack a union"); | 5648 | zig_panic("TODO bit pack a union"); |
| 5625 | case ZigTypeIdStruct: | 5649 | case ZigTypeIdStruct: |
| ... | @@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c | ... | @@ -5992,6 +6016,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c |
| 5992 | } | 6016 | } |
| 5993 | } | 6017 | } |
| 5994 | } | 6018 | } |
| 6019 | case ZigTypeIdVector: { | ||
| 6020 | uint32_t len = type_entry->data.vector.len; | ||
| 6021 | LLVMValueRef *values = allocate<LLVMValueRef>(len); | ||
| 6022 | for (uint32_t i = 0; i < len; i += 1) { | ||
| 6023 | values[i] = gen_const_val(g, &const_val->data.x_vector.elements[i], ""); | ||
| 6024 | } | ||
| 6025 | return LLVMConstVector(values, len); | ||
| 6026 | } | ||
| 5995 | case ZigTypeIdUnion: | 6027 | case ZigTypeIdUnion: |
| 5996 | { | 6028 | { |
| 5997 | LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; | 6029 | LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; |
| ... | @@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -6927,6 +6959,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 6927 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); | 6959 | create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); |
| 6928 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); | 6960 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); |
| 6929 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int | 6961 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int |
| 6962 | create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); | ||
| 6930 | create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); | 6963 | create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); |
| 6931 | create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); | 6964 | create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); |
| 6932 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); | 6965 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); |
| ... | @@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -7152,6 +7185,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7152 | " ArgTuple: void,\n" | 7185 | " ArgTuple: void,\n" |
| 7153 | " Opaque: void,\n" | 7186 | " Opaque: void,\n" |
| 7154 | " Promise: Promise,\n" | 7187 | " Promise: Promise,\n" |
| 7188 | " Vector: Vector,\n" | ||
| 7155 | "\n\n" | 7189 | "\n\n" |
| 7156 | " pub const Int = struct {\n" | 7190 | " pub const Int = struct {\n" |
| 7157 | " is_signed: bool,\n" | 7191 | " is_signed: bool,\n" |
| ... | @@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -7270,6 +7304,11 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7270 | " child: ?type,\n" | 7304 | " child: ?type,\n" |
| 7271 | " };\n" | 7305 | " };\n" |
| 7272 | "\n" | 7306 | "\n" |
| 7307 | " pub const Vector = struct {\n" | ||
| 7308 | " len: u32,\n" | ||
| 7309 | " child: type,\n" | ||
| 7310 | " };\n" | ||
| 7311 | "\n" | ||
| 7273 | " pub const Definition = struct {\n" | 7312 | " pub const Definition = struct {\n" |
| 7274 | " name: []const u8,\n" | 7313 | " name: []const u8,\n" |
| 7275 | " is_pub: bool,\n" | 7314 | " is_pub: bool,\n" |
| ... | @@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e | ... | @@ -7841,6 +7880,9 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e |
| 7841 | case ZigTypeIdArray: | 7880 | case ZigTypeIdArray: |
| 7842 | prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); | 7881 | prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); |
| 7843 | return; | 7882 | return; |
| 7883 | case ZigTypeIdVector: | ||
| 7884 | prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type); | ||
| 7885 | return; | ||
| 7844 | case ZigTypeIdOptional: | 7886 | case ZigTypeIdOptional: |
| 7845 | prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); | 7887 | prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); |
| 7846 | return; | 7888 | return; |
| ... | @@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu | ... | @@ -7972,6 +8014,8 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu |
| 7972 | buf_appendf(out_buf, "%s", buf_ptr(child_buf)); | 8014 | buf_appendf(out_buf, "%s", buf_ptr(child_buf)); |
| 7973 | return; | 8015 | return; |
| 7974 | } | 8016 | } |
| 8017 | case ZigTypeIdVector: | ||
| 8018 | zig_panic("TODO implement get_c_type for vector types"); | ||
| 7975 | case ZigTypeIdErrorUnion: | 8019 | case ZigTypeIdErrorUnion: |
| 7976 | case ZigTypeIdErrorSet: | 8020 | case ZigTypeIdErrorSet: |
| 7977 | case ZigTypeIdFn: | 8021 | case ZigTypeIdFn: |
| ... | @@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) { | ... | @@ -8137,6 +8181,7 @@ static void gen_h_file(CodeGen *g) { |
| 8137 | case ZigTypeIdOptional: | 8181 | case ZigTypeIdOptional: |
| 8138 | case ZigTypeIdFn: | 8182 | case ZigTypeIdFn: |
| 8139 | case ZigTypeIdPromise: | 8183 | case ZigTypeIdPromise: |
| 8184 | case ZigTypeIdVector: | ||
| 8140 | zig_unreachable(); | 8185 | zig_unreachable(); |
| 8141 | case ZigTypeIdEnum: | 8186 | case ZigTypeIdEnum: |
| 8142 | if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { | 8187 | if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { |
src/ir.cpp+168-45| ... | @@ -587,6 +587,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { | ... | @@ -587,6 +587,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { |
| 587 | return IrInstructionIdIntType; | 587 | return IrInstructionIdIntType; |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) { | ||
| 591 | return IrInstructionIdVectorType; | ||
| 592 | } | ||
| 593 | |||
| 590 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { | 594 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { |
| 591 | return IrInstructionIdBoolNot; | 595 | return IrInstructionIdBoolNot; |
| 592 | } | 596 | } |
| ... | @@ -1953,6 +1957,19 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1953,6 +1957,19 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1953 | return &instruction->base; | 1957 | return &instruction->base; |
| 1954 | } | 1958 | } |
| 1955 | 1959 | ||
| 1960 | static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len, | ||
| 1961 | IrInstruction *elem_type) | ||
| 1962 | { | ||
| 1963 | IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node); | ||
| 1964 | instruction->len = len; | ||
| 1965 | instruction->elem_type = elem_type; | ||
| 1966 | |||
| 1967 | ir_ref_instruction(len, irb->current_basic_block); | ||
| 1968 | ir_ref_instruction(elem_type, irb->current_basic_block); | ||
| 1969 | |||
| 1970 | return &instruction->base; | ||
| 1971 | } | ||
| 1972 | |||
| 1956 | static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1973 | static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1957 | IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); | 1974 | IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); |
| 1958 | instruction->value = value; | 1975 | instruction->value = value; |
| ... | @@ -4230,6 +4247,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4230,6 +4247,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4230 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); | 4247 | IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); |
| 4231 | return ir_lval_wrap(irb, scope, int_type, lval); | 4248 | return ir_lval_wrap(irb, scope, int_type, lval); |
| 4232 | } | 4249 | } |
| 4250 | case BuiltinFnIdVectorType: | ||
| 4251 | { | ||
| 4252 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4253 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4254 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4255 | return arg0_value; | ||
| 4256 | |||
| 4257 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4258 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4259 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4260 | return arg1_value; | ||
| 4261 | |||
| 4262 | IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); | ||
| 4263 | return ir_lval_wrap(irb, scope, vector_type, lval); | ||
| 4264 | } | ||
| 4233 | case BuiltinFnIdMemcpy: | 4265 | case BuiltinFnIdMemcpy: |
| 4234 | { | 4266 | { |
| 4235 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4267 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -11617,6 +11649,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -11617,6 +11649,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 11617 | case ZigTypeIdComptimeInt: | 11649 | case ZigTypeIdComptimeInt: |
| 11618 | case ZigTypeIdInt: | 11650 | case ZigTypeIdInt: |
| 11619 | case ZigTypeIdFloat: | 11651 | case ZigTypeIdFloat: |
| 11652 | case ZigTypeIdVector: | ||
| 11620 | operator_allowed = true; | 11653 | operator_allowed = true; |
| 11621 | break; | 11654 | break; |
| 11622 | 11655 | ||
| ... | @@ -12032,6 +12065,48 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b | ... | @@ -12032,6 +12065,48 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b |
| 12032 | return result; | 12065 | return result; |
| 12033 | } | 12066 | } |
| 12034 | 12067 | ||
| 12068 | static bool ok_float_op(IrBinOp op) { | ||
| 12069 | switch (op) { | ||
| 12070 | case IrBinOpInvalid: | ||
| 12071 | zig_unreachable(); | ||
| 12072 | case IrBinOpAdd: | ||
| 12073 | case IrBinOpSub: | ||
| 12074 | case IrBinOpMult: | ||
| 12075 | case IrBinOpDivUnspecified: | ||
| 12076 | case IrBinOpDivTrunc: | ||
| 12077 | case IrBinOpDivFloor: | ||
| 12078 | case IrBinOpDivExact: | ||
| 12079 | case IrBinOpRemRem: | ||
| 12080 | case IrBinOpRemMod: | ||
| 12081 | return true; | ||
| 12082 | |||
| 12083 | case IrBinOpBoolOr: | ||
| 12084 | case IrBinOpBoolAnd: | ||
| 12085 | case IrBinOpCmpEq: | ||
| 12086 | case IrBinOpCmpNotEq: | ||
| 12087 | case IrBinOpCmpLessThan: | ||
| 12088 | case IrBinOpCmpGreaterThan: | ||
| 12089 | case IrBinOpCmpLessOrEq: | ||
| 12090 | case IrBinOpCmpGreaterOrEq: | ||
| 12091 | case IrBinOpBinOr: | ||
| 12092 | case IrBinOpBinXor: | ||
| 12093 | case IrBinOpBinAnd: | ||
| 12094 | case IrBinOpBitShiftLeftLossy: | ||
| 12095 | case IrBinOpBitShiftLeftExact: | ||
| 12096 | case IrBinOpBitShiftRightLossy: | ||
| 12097 | case IrBinOpBitShiftRightExact: | ||
| 12098 | case IrBinOpAddWrap: | ||
| 12099 | case IrBinOpSubWrap: | ||
| 12100 | case IrBinOpMultWrap: | ||
| 12101 | case IrBinOpRemUnspecified: | ||
| 12102 | case IrBinOpArrayCat: | ||
| 12103 | case IrBinOpArrayMult: | ||
| 12104 | case IrBinOpMergeErrorSets: | ||
| 12105 | return false; | ||
| 12106 | } | ||
| 12107 | zig_unreachable(); | ||
| 12108 | } | ||
| 12109 | |||
| 12035 | static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { | 12110 | static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { |
| 12036 | IrInstruction *op1 = instruction->op1->child; | 12111 | IrInstruction *op1 = instruction->op1->child; |
| 12037 | if (type_is_invalid(op1->value.type)) | 12112 | if (type_is_invalid(op1->value.type)) |
| ... | @@ -12169,21 +12244,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -12169,21 +12244,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 12169 | op_id = IrBinOpRemRem; | 12244 | op_id = IrBinOpRemRem; |
| 12170 | } | 12245 | } |
| 12171 | 12246 | ||
| 12247 | bool ok = false; | ||
| 12172 | if (is_int) { | 12248 | if (is_int) { |
| 12173 | // int | 12249 | ok = true; |
| 12174 | } else if (is_float && | 12250 | } else if (is_float && ok_float_op(op_id)) { |
| 12175 | (op_id == IrBinOpAdd || | 12251 | ok = true; |
| 12176 | op_id == IrBinOpSub || | 12252 | } else if (resolved_type->id == ZigTypeIdVector) { |
| 12177 | op_id == IrBinOpMult || | 12253 | ZigType *elem_type = resolved_type->data.vector.elem_type; |
| 12178 | op_id == IrBinOpDivUnspecified || | 12254 | if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) { |
| 12179 | op_id == IrBinOpDivTrunc || | 12255 | ok = true; |
| 12180 | op_id == IrBinOpDivFloor || | 12256 | } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) { |
| 12181 | op_id == IrBinOpDivExact || | 12257 | ok = true; |
| 12182 | op_id == IrBinOpRemRem || | 12258 | } |
| 12183 | op_id == IrBinOpRemMod)) | 12259 | } |
| 12184 | { | 12260 | if (!ok) { |
| 12185 | // float | ||
| 12186 | } else { | ||
| 12187 | AstNode *source_node = instruction->base.source_node; | 12261 | AstNode *source_node = instruction->base.source_node; |
| 12188 | ir_add_error_node(ira, source_node, | 12262 | ir_add_error_node(ira, source_node, |
| 12189 | buf_sprintf("invalid operands to binary expression: '%s' and '%s'", | 12263 | buf_sprintf("invalid operands to binary expression: '%s' and '%s'", |
| ... | @@ -12817,6 +12891,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -12817,6 +12891,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 12817 | case ZigTypeIdPointer: | 12891 | case ZigTypeIdPointer: |
| 12818 | case ZigTypeIdArray: | 12892 | case ZigTypeIdArray: |
| 12819 | case ZigTypeIdBool: | 12893 | case ZigTypeIdBool: |
| 12894 | case ZigTypeIdVector: | ||
| 12820 | break; | 12895 | break; |
| 12821 | case ZigTypeIdMetaType: | 12896 | case ZigTypeIdMetaType: |
| 12822 | case ZigTypeIdVoid: | 12897 | case ZigTypeIdVoid: |
| ... | @@ -12851,6 +12926,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -12851,6 +12926,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 12851 | case ZigTypeIdOptional: | 12926 | case ZigTypeIdOptional: |
| 12852 | case ZigTypeIdErrorUnion: | 12927 | case ZigTypeIdErrorUnion: |
| 12853 | case ZigTypeIdErrorSet: | 12928 | case ZigTypeIdErrorSet: |
| 12929 | case ZigTypeIdVector: | ||
| 12854 | zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); | 12930 | zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); |
| 12855 | case ZigTypeIdNamespace: | 12931 | case ZigTypeIdNamespace: |
| 12856 | case ZigTypeIdBoundFn: | 12932 | case ZigTypeIdBoundFn: |
| ... | @@ -14009,6 +14085,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_ | ... | @@ -14009,6 +14085,7 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_ |
| 14009 | case ZigTypeIdVoid: | 14085 | case ZigTypeIdVoid: |
| 14010 | case ZigTypeIdBool: | 14086 | case ZigTypeIdBool: |
| 14011 | case ZigTypeIdInt: | 14087 | case ZigTypeIdInt: |
| 14088 | case ZigTypeIdVector: | ||
| 14012 | case ZigTypeIdFloat: | 14089 | case ZigTypeIdFloat: |
| 14013 | case ZigTypeIdPointer: | 14090 | case ZigTypeIdPointer: |
| 14014 | case ZigTypeIdArray: | 14091 | case ZigTypeIdArray: |
| ... | @@ -15383,37 +15460,7 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio | ... | @@ -15383,37 +15460,7 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio |
| 15383 | ZigType *type_entry = expr_value->value.type; | 15460 | ZigType *type_entry = expr_value->value.type; |
| 15384 | if (type_is_invalid(type_entry)) | 15461 | if (type_is_invalid(type_entry)) |
| 15385 | return ira->codegen->invalid_instruction; | 15462 | return ira->codegen->invalid_instruction; |
| 15386 | switch (type_entry->id) { | 15463 | return ir_const_type(ira, &typeof_instruction->base, type_entry); |
| 15387 | case ZigTypeIdInvalid: | ||
| 15388 | zig_unreachable(); // handled above | ||
| 15389 | case ZigTypeIdComptimeFloat: | ||
| 15390 | case ZigTypeIdComptimeInt: | ||
| 15391 | case ZigTypeIdUndefined: | ||
| 15392 | case ZigTypeIdNull: | ||
| 15393 | case ZigTypeIdNamespace: | ||
| 15394 | case ZigTypeIdBoundFn: | ||
| 15395 | case ZigTypeIdMetaType: | ||
| 15396 | case ZigTypeIdVoid: | ||
| 15397 | case ZigTypeIdBool: | ||
| 15398 | case ZigTypeIdUnreachable: | ||
| 15399 | case ZigTypeIdInt: | ||
| 15400 | case ZigTypeIdFloat: | ||
| 15401 | case ZigTypeIdPointer: | ||
| 15402 | case ZigTypeIdArray: | ||
| 15403 | case ZigTypeIdStruct: | ||
| 15404 | case ZigTypeIdOptional: | ||
| 15405 | case ZigTypeIdErrorUnion: | ||
| 15406 | case ZigTypeIdErrorSet: | ||
| 15407 | case ZigTypeIdEnum: | ||
| 15408 | case ZigTypeIdUnion: | ||
| 15409 | case ZigTypeIdFn: | ||
| 15410 | case ZigTypeIdArgTuple: | ||
| 15411 | case ZigTypeIdOpaque: | ||
| 15412 | case ZigTypeIdPromise: | ||
| 15413 | return ir_const_type(ira, &typeof_instruction->base, type_entry); | ||
| 15414 | } | ||
| 15415 | |||
| 15416 | zig_unreachable(); | ||
| 15417 | } | 15464 | } |
| 15418 | 15465 | ||
| 15419 | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, | 15466 | static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, |
| ... | @@ -15652,6 +15699,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -15652,6 +15699,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 15652 | case ZigTypeIdNamespace: | 15699 | case ZigTypeIdNamespace: |
| 15653 | case ZigTypeIdBoundFn: | 15700 | case ZigTypeIdBoundFn: |
| 15654 | case ZigTypeIdPromise: | 15701 | case ZigTypeIdPromise: |
| 15702 | case ZigTypeIdVector: | ||
| 15655 | { | 15703 | { |
| 15656 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) | 15704 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) |
| 15657 | return ira->codegen->invalid_instruction; | 15705 | return ira->codegen->invalid_instruction; |
| ... | @@ -15772,6 +15820,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, | ... | @@ -15772,6 +15820,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 15772 | case ZigTypeIdNamespace: | 15820 | case ZigTypeIdNamespace: |
| 15773 | case ZigTypeIdBoundFn: | 15821 | case ZigTypeIdBoundFn: |
| 15774 | case ZigTypeIdPromise: | 15822 | case ZigTypeIdPromise: |
| 15823 | case ZigTypeIdVector: | ||
| 15775 | { | 15824 | { |
| 15776 | if ((err = ensure_complete_type(ira->codegen, child_type))) | 15825 | if ((err = ensure_complete_type(ira->codegen, child_type))) |
| 15777 | return ira->codegen->invalid_instruction; | 15826 | return ira->codegen->invalid_instruction; |
| ... | @@ -15838,6 +15887,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, | ... | @@ -15838,6 +15887,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 15838 | case ZigTypeIdUnion: | 15887 | case ZigTypeIdUnion: |
| 15839 | case ZigTypeIdFn: | 15888 | case ZigTypeIdFn: |
| 15840 | case ZigTypeIdPromise: | 15889 | case ZigTypeIdPromise: |
| 15890 | case ZigTypeIdVector: | ||
| 15841 | { | 15891 | { |
| 15842 | uint64_t size_in_bytes = type_size(ira->codegen, type_entry); | 15892 | uint64_t size_in_bytes = type_size(ira->codegen, type_entry); |
| 15843 | return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes); | 15893 | return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes); |
| ... | @@ -16307,6 +16357,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, | ... | @@ -16307,6 +16357,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 16307 | case ZigTypeIdBoundFn: | 16357 | case ZigTypeIdBoundFn: |
| 16308 | case ZigTypeIdArgTuple: | 16358 | case ZigTypeIdArgTuple: |
| 16309 | case ZigTypeIdOpaque: | 16359 | case ZigTypeIdOpaque: |
| 16360 | case ZigTypeIdVector: | ||
| 16310 | ir_add_error(ira, &switch_target_instruction->base, | 16361 | ir_add_error(ira, &switch_target_instruction->base, |
| 16311 | buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); | 16362 | buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); |
| 16312 | return ira->codegen->invalid_instruction; | 16363 | return ira->codegen->invalid_instruction; |
| ... | @@ -17496,6 +17547,27 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE | ... | @@ -17496,6 +17547,27 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE |
| 17496 | 17547 | ||
| 17497 | break; | 17548 | break; |
| 17498 | } | 17549 | } |
| 17550 | case ZigTypeIdVector: { | ||
| 17551 | result = create_const_vals(1); | ||
| 17552 | result->special = ConstValSpecialStatic; | ||
| 17553 | result->type = ir_type_info_get_type(ira, "Vector", nullptr); | ||
| 17554 | |||
| 17555 | ConstExprValue *fields = create_const_vals(2); | ||
| 17556 | result->data.x_struct.fields = fields; | ||
| 17557 | |||
| 17558 | // len: usize | ||
| 17559 | ensure_field_index(result->type, "len", 0); | ||
| 17560 | fields[0].special = ConstValSpecialStatic; | ||
| 17561 | fields[0].type = ira->codegen->builtin_types.entry_u32; | ||
| 17562 | bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len); | ||
| 17563 | // child: type | ||
| 17564 | ensure_field_index(result->type, "child", 1); | ||
| 17565 | fields[1].special = ConstValSpecialStatic; | ||
| 17566 | fields[1].type = ira->codegen->builtin_types.entry_type; | ||
| 17567 | fields[1].data.x_type = type_entry->data.vector.elem_type; | ||
| 17568 | |||
| 17569 | break; | ||
| 17570 | } | ||
| 17499 | case ZigTypeIdOptional: | 17571 | case ZigTypeIdOptional: |
| 17500 | { | 17572 | { |
| 17501 | result = create_const_vals(1); | 17573 | result = create_const_vals(1); |
| ... | @@ -18671,6 +18743,30 @@ static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruct | ... | @@ -18671,6 +18743,30 @@ static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstruct |
| 18671 | return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); | 18743 | return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); |
| 18672 | } | 18744 | } |
| 18673 | 18745 | ||
| 18746 | static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) { | ||
| 18747 | uint64_t len; | ||
| 18748 | if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) | ||
| 18749 | return ira->codegen->invalid_instruction; | ||
| 18750 | |||
| 18751 | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); | ||
| 18752 | if (type_is_invalid(elem_type)) | ||
| 18753 | return ira->codegen->invalid_instruction; | ||
| 18754 | |||
| 18755 | if (elem_type->id != ZigTypeIdInt && | ||
| 18756 | elem_type->id != ZigTypeIdFloat && | ||
| 18757 | get_codegen_ptr_type(elem_type) == nullptr) | ||
| 18758 | { | ||
| 18759 | ir_add_error(ira, instruction->elem_type, | ||
| 18760 | buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid", | ||
| 18761 | buf_ptr(&elem_type->name))); | ||
| 18762 | return ira->codegen->invalid_instruction; | ||
| 18763 | } | ||
| 18764 | |||
| 18765 | ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); | ||
| 18766 | |||
| 18767 | return ir_const_type(ira, &instruction->base, vector_type); | ||
| 18768 | } | ||
| 18769 | |||
| 18674 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { | 18770 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { |
| 18675 | IrInstruction *value = instruction->value->child; | 18771 | IrInstruction *value = instruction->value->child; |
| 18676 | if (type_is_invalid(value->value.type)) | 18772 | if (type_is_invalid(value->value.type)) |
| ... | @@ -19474,6 +19570,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct | ... | @@ -19474,6 +19570,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 19474 | case ZigTypeIdEnum: | 19570 | case ZigTypeIdEnum: |
| 19475 | case ZigTypeIdUnion: | 19571 | case ZigTypeIdUnion: |
| 19476 | case ZigTypeIdFn: | 19572 | case ZigTypeIdFn: |
| 19573 | case ZigTypeIdVector: | ||
| 19477 | { | 19574 | { |
| 19478 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); | 19575 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 19479 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); | 19576 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); |
| ... | @@ -20311,6 +20408,15 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -20311,6 +20408,15 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20311 | } | 20408 | } |
| 20312 | } | 20409 | } |
| 20313 | return; | 20410 | return; |
| 20411 | case ZigTypeIdVector: { | ||
| 20412 | size_t buf_i = 0; | ||
| 20413 | for (uint32_t elem_i = 0; elem_i < val->type->data.vector.len; elem_i += 1) { | ||
| 20414 | ConstExprValue *elem = &val->data.x_vector.elements[elem_i]; | ||
| 20415 | buf_write_value_bytes(codegen, &buf[buf_i], elem); | ||
| 20416 | buf_i += type_size(codegen, elem->type); | ||
| 20417 | } | ||
| 20418 | return; | ||
| 20419 | } | ||
| 20314 | case ZigTypeIdStruct: | 20420 | case ZigTypeIdStruct: |
| 20315 | zig_panic("TODO buf_write_value_bytes struct type"); | 20421 | zig_panic("TODO buf_write_value_bytes struct type"); |
| 20316 | case ZigTypeIdOptional: | 20422 | case ZigTypeIdOptional: |
| ... | @@ -20387,6 +20493,20 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -20387,6 +20493,20 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 20387 | } | 20493 | } |
| 20388 | zig_unreachable(); | 20494 | zig_unreachable(); |
| 20389 | } | 20495 | } |
| 20496 | case ZigTypeIdVector: { | ||
| 20497 | uint64_t elem_size = type_size(codegen, val->type->data.vector.elem_type); | ||
| 20498 | uint32_t len = val->type->data.vector.len; | ||
| 20499 | |||
| 20500 | val->data.x_vector.elements = create_const_vals(len); | ||
| 20501 | for (uint32_t i = 0; i < len; i += 1) { | ||
| 20502 | ConstExprValue *elem = &val->data.x_vector.elements[i]; | ||
| 20503 | elem->special = ConstValSpecialStatic; | ||
| 20504 | elem->type = val->type->data.vector.elem_type; | ||
| 20505 | if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) | ||
| 20506 | return err; | ||
| 20507 | } | ||
| 20508 | return ErrorNone; | ||
| 20509 | } | ||
| 20390 | case ZigTypeIdEnum: | 20510 | case ZigTypeIdEnum: |
| 20391 | switch (val->type->data.enumeration.layout) { | 20511 | switch (val->type->data.enumeration.layout) { |
| 20392 | case ContainerLayoutAuto: | 20512 | case ContainerLayoutAuto: |
| ... | @@ -21633,6 +21753,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -21633,6 +21753,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 21633 | return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); | 21753 | return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); |
| 21634 | case IrInstructionIdIntType: | 21754 | case IrInstructionIdIntType: |
| 21635 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); | 21755 | return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); |
| 21756 | case IrInstructionIdVectorType: | ||
| 21757 | return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); | ||
| 21636 | case IrInstructionIdBoolNot: | 21758 | case IrInstructionIdBoolNot: |
| 21637 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); | 21759 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); |
| 21638 | case IrInstructionIdMemset: | 21760 | case IrInstructionIdMemset: |
| ... | @@ -21943,6 +22065,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -21943,6 +22065,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 21943 | case IrInstructionIdEmbedFile: | 22065 | case IrInstructionIdEmbedFile: |
| 21944 | case IrInstructionIdTruncate: | 22066 | case IrInstructionIdTruncate: |
| 21945 | case IrInstructionIdIntType: | 22067 | case IrInstructionIdIntType: |
| 22068 | case IrInstructionIdVectorType: | ||
| 21946 | case IrInstructionIdBoolNot: | 22069 | case IrInstructionIdBoolNot: |
| 21947 | case IrInstructionIdSlice: | 22070 | case IrInstructionIdSlice: |
| 21948 | case IrInstructionIdMemberCount: | 22071 | case IrInstructionIdMemberCount: |
src/ir_print.cpp+11| ... | @@ -719,6 +719,14 @@ static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { | ... | @@ -719,6 +719,14 @@ static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { |
| 719 | fprintf(irp->f, ")"); | 719 | fprintf(irp->f, ")"); |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | static void ir_print_vector_type(IrPrint *irp, IrInstructionVectorType *instruction) { | ||
| 723 | fprintf(irp->f, "@Vector("); | ||
| 724 | ir_print_other_instruction(irp, instruction->len); | ||
| 725 | fprintf(irp->f, ", "); | ||
| 726 | ir_print_other_instruction(irp, instruction->elem_type); | ||
| 727 | fprintf(irp->f, ")"); | ||
| 728 | } | ||
| 729 | |||
| 722 | static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) { | 730 | static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) { |
| 723 | fprintf(irp->f, "! "); | 731 | fprintf(irp->f, "! "); |
| 724 | ir_print_other_instruction(irp, instruction->value); | 732 | ir_print_other_instruction(irp, instruction->value); |
| ... | @@ -1577,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1577,6 +1585,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1577 | case IrInstructionIdIntType: | 1585 | case IrInstructionIdIntType: |
| 1578 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); | 1586 | ir_print_int_type(irp, (IrInstructionIntType *)instruction); |
| 1579 | break; | 1587 | break; |
| 1588 | case IrInstructionIdVectorType: | ||
| 1589 | ir_print_vector_type(irp, (IrInstructionVectorType *)instruction); | ||
| 1590 | break; | ||
| 1580 | case IrInstructionIdBoolNot: | 1591 | case IrInstructionIdBoolNot: |
| 1581 | ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction); | 1592 | ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction); |
| 1582 | break; | 1593 | break; |
src/zig_llvm.cpp+13| ... | @@ -263,6 +263,19 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch | ... | @@ -263,6 +263,19 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch |
| 263 | return reinterpret_cast<ZigLLVMDIType*>(di_type); | 263 | return reinterpret_cast<ZigLLVMDIType*>(di_type); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder, | ||
| 267 | uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty) | ||
| 268 | { | ||
| 269 | SmallVector<Metadata *, 1> subrange; | ||
| 270 | subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, Size)); | ||
| 271 | DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createVectorType( | ||
| 272 | Size, | ||
| 273 | AlignInBits, | ||
| 274 | reinterpret_cast<DIType*>(Ty), | ||
| 275 | reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange)); | ||
| 276 | return reinterpret_cast<ZigLLVMDIType*>(di_type); | ||
| 277 | } | ||
| 278 | |||
| 266 | ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits, | 279 | ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits, |
| 267 | uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count) | 280 | uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count) |
| 268 | { | 281 | { |
src/zig_llvm.h+3| ... | @@ -191,6 +191,9 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB | ... | @@ -191,6 +191,9 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB |
| 191 | unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, | 191 | unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, |
| 192 | unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram); | 192 | unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram); |
| 193 | 193 | ||
| 194 | ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder, | ||
| 195 | uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty); | ||
| 196 | |||
| 194 | ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram); | 197 | ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram); |
| 195 | 198 | ||
| 196 | ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); | 199 | ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); |
std/hash_map.zig+2| ... | @@ -508,6 +508,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type | ... | @@ -508,6 +508,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type |
| 508 | 508 | ||
| 509 | builtin.TypeId.Optional => @compileError("TODO auto hash for optionals"), | 509 | builtin.TypeId.Optional => @compileError("TODO auto hash for optionals"), |
| 510 | builtin.TypeId.Array => @compileError("TODO auto hash for arrays"), | 510 | builtin.TypeId.Array => @compileError("TODO auto hash for arrays"), |
| 511 | builtin.TypeId.Vector => @compileError("TODO auto hash for vectors"), | ||
| 511 | builtin.TypeId.Struct => @compileError("TODO auto hash for structs"), | 512 | builtin.TypeId.Struct => @compileError("TODO auto hash for structs"), |
| 512 | builtin.TypeId.Union => @compileError("TODO auto hash for unions"), | 513 | builtin.TypeId.Union => @compileError("TODO auto hash for unions"), |
| 513 | builtin.TypeId.ErrorUnion => @compileError("TODO auto hash for unions"), | 514 | builtin.TypeId.ErrorUnion => @compileError("TODO auto hash for unions"), |
| ... | @@ -555,5 +556,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool { | ... | @@ -555,5 +556,6 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool { |
| 555 | builtin.TypeId.Struct => @compileError("TODO auto eql for structs"), | 556 | builtin.TypeId.Struct => @compileError("TODO auto eql for structs"), |
| 556 | builtin.TypeId.Union => @compileError("TODO auto eql for unions"), | 557 | builtin.TypeId.Union => @compileError("TODO auto eql for unions"), |
| 557 | builtin.TypeId.ErrorUnion => @compileError("TODO auto eql for unions"), | 558 | builtin.TypeId.ErrorUnion => @compileError("TODO auto eql for unions"), |
| 559 | builtin.TypeId.Vector => @compileError("TODO auto eql for vectors"), | ||
| 558 | } | 560 | } |
| 559 | } | 561 | } |
test/stage1/behavior/type_info.zig+14-2| ... | @@ -171,11 +171,11 @@ fn testUnion() void { | ... | @@ -171,11 +171,11 @@ fn testUnion() void { |
| 171 | assertOrPanic(TypeId(typeinfo_info) == TypeId.Union); | 171 | assertOrPanic(TypeId(typeinfo_info) == TypeId.Union); |
| 172 | assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto); | 172 | assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto); |
| 173 | assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId); | 173 | assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId); |
| 174 | assertOrPanic(typeinfo_info.Union.fields.len == 24); | 174 | assertOrPanic(typeinfo_info.Union.fields.len == 25); |
| 175 | assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null); | 175 | assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null); |
| 176 | assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4); | 176 | assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4); |
| 177 | assertOrPanic(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); | 177 | assertOrPanic(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); |
| 178 | assertOrPanic(typeinfo_info.Union.defs.len == 20); | 178 | assertOrPanic(typeinfo_info.Union.defs.len == 21); |
| 179 | 179 | ||
| 180 | const TestNoTagUnion = union { | 180 | const TestNoTagUnion = union { |
| 181 | Foo: void, | 181 | Foo: void, |
| ... | @@ -262,3 +262,15 @@ test "typeInfo with comptime parameter in struct fn def" { | ... | @@ -262,3 +262,15 @@ test "typeInfo with comptime parameter in struct fn def" { |
| 262 | }; | 262 | }; |
| 263 | comptime var info = @typeInfo(S); | 263 | comptime var info = @typeInfo(S); |
| 264 | } | 264 | } |
| 265 | |||
| 266 | test "type info: vectors" { | ||
| 267 | testVector(); | ||
| 268 | comptime testVector(); | ||
| 269 | } | ||
| 270 | |||
| 271 | fn testVector() void { | ||
| 272 | const vec_info = @typeInfo(@Vector(4, i32)); | ||
| 273 | assertOrPanic(TypeId(vec_info) == TypeId.Vector); | ||
| 274 | assertOrPanic(vec_info.Vector.len == 4); | ||
| 275 | assertOrPanic(vec_info.Vector.child == i32); | ||
| 276 | } |