diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 57 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 106 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 18 |
3 files changed, 100 insertions, 81 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index f5a1036479..c62abdb3f6 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap( true, ); +const FormatTypeAsCIdentContext = struct { + ty: Type, + target: std.Target, +}; + +/// TODO make this not cut off at 128 bytes fn formatTypeAsCIdentifier( - data: Type, + data: FormatTypeAsCIdentContext, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype, @@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier( _ = fmt; _ = options; var buffer = [1]u8{0} ** 128; - // We don't care if it gets cut off, it's still more unique than a number - var buf = std.fmt.bufPrint(&buffer, "{}", .{data}) catch &buffer; + var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer; return formatIdent(buf, "", .{}, writer); } -pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) { - return .{ .data = t }; +pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) { + return .{ .data = .{ + .ty = ty, + .target = target, + } }; } const reserved_idents = std.ComptimeStringMap(void, .{ @@ -369,6 +377,8 @@ pub const DeclGen = struct { ) error{ OutOfMemory, AnalysisFail }!void { decl.markAlive(); + const target = dg.module.getTarget(); + if (ty.isSlice()) { try writer.writeByte('('); try dg.renderTypecast(writer, ty); @@ -376,7 +386,7 @@ pub const DeclGen = struct { var buf: Type.SlicePtrFieldTypeBuffer = undefined; try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr()); try writer.writeAll(", "); - try writer.print("{d}", .{val.sliceLen()}); + try writer.print("{d}", .{val.sliceLen(target)}); try writer.writeAll("}"); return; } @@ -388,7 +398,7 @@ pub const DeclGen = struct { // somewhere and we should let the C compiler tell us about it. if (ty.castPtrToFn() == null) { // Determine if we must pointer cast. - if (ty.eql(decl.ty)) { + if (ty.eql(decl.ty, target)) { try writer.writeByte('&'); try dg.renderDeclName(writer, decl); return; @@ -508,6 +518,7 @@ pub const DeclGen = struct { ty: Type, val: Value, ) error{ OutOfMemory, AnalysisFail }!void { + const target = dg.module.getTarget(); if (val.isUndefDeep()) { switch (ty.zigTypeTag()) { // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang) @@ -551,7 +562,7 @@ pub const DeclGen = struct { else => { if (ty.isSignedInt()) return writer.print("{d}", .{val.toSignedInt()}); - return writer.print("{d}u", .{val.toUnsignedInt()}); + return writer.print("{d}u", .{val.toUnsignedInt(target)}); }, }, .Float => { @@ -609,7 +620,7 @@ pub const DeclGen = struct { .int_u64, .one => { try writer.writeAll("(("); try dg.renderTypecast(writer, ty); - try writer.print(")0x{x}u)", .{val.toUnsignedInt()}); + try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)}); }, else => unreachable, }, @@ -653,7 +664,6 @@ pub const DeclGen = struct { if (ty.isPtrLikeOptional()) { return dg.renderValue(writer, payload_type, val); } - const target = dg.module.getTarget(); if (payload_type.abiSize(target) == 0) { const is_null = val.castTag(.opt_payload) == null; return writer.print("{}", .{is_null}); @@ -773,7 +783,6 @@ pub const DeclGen = struct { .Union => { const union_obj = val.castTag(.@"union").?.data; const union_ty = ty.cast(Type.Payload.Union).?.data; - const target = dg.module.getTarget(); const layout = ty.unionGetLayout(target); try writer.writeAll("("); @@ -789,7 +798,7 @@ pub const DeclGen = struct { try writer.writeAll(".payload = {"); } - const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?; + const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?; const field_ty = ty.unionFields().values()[index].ty; const field_name = ty.unionFields().keys()[index]; if (field_ty.hasRuntimeBits()) { @@ -879,8 +888,8 @@ pub const DeclGen = struct { try bw.writeAll(" (*"); const name_start = buffer.items.len; - // TODO: typeToCIdentifier truncates to 128 bytes, we probably don't want to do this - try bw.print("zig_F_{s})(", .{typeToCIdentifier(t)}); + const target = dg.module.getTarget(); + try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)}); const name_end = buffer.items.len - 2; const param_len = fn_info.param_types.len; @@ -934,10 +943,11 @@ pub const DeclGen = struct { try bw.writeAll("; size_t len; } "); const name_index = buffer.items.len; + const target = dg.module.getTarget(); if (t.isConstPtr()) { - try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)}); + try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)}); } else { - try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)}); + try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)}); } if (ptr_sentinel) |s| { try bw.writeAll("_s_"); @@ -1023,7 +1033,8 @@ pub const DeclGen = struct { try buffer.appendSlice("} "); const name_start = buffer.items.len; - try writer.print("zig_T_{};\n", .{typeToCIdentifier(t)}); + const target = dg.module.getTarget(); + try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, target)}); const rendered = buffer.toOwnedSlice(); errdefer dg.typedefs.allocator.free(rendered); @@ -1107,6 +1118,7 @@ pub const DeclGen = struct { try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0); try bw.writeAll("; uint16_t error; } "); const name_index = buffer.items.len; + const target = dg.module.getTarget(); if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { const func = inf_err_set_payload.data.func; try bw.writeAll("zig_E_"); @@ -1114,7 +1126,7 @@ pub const DeclGen = struct { try bw.writeAll(";\n"); } else { try bw.print("zig_E_{s}_{s};\n", .{ - typeToCIdentifier(err_set_type), typeToCIdentifier(child_type), + typeToCIdentifier(err_set_type, target), typeToCIdentifier(child_type, target), }); } @@ -1144,7 +1156,8 @@ pub const DeclGen = struct { try dg.renderType(bw, elem_type); const name_start = buffer.items.len + 1; - try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type), c_len }); + const target = dg.module.getTarget(); + try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, target), c_len }); const name_end = buffer.items.len; try bw.print("[{d}];\n", .{c_len}); @@ -1172,7 +1185,8 @@ pub const DeclGen = struct { try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0); try bw.writeAll("; bool is_null; } "); const name_index = buffer.items.len; - try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type)}); + const target = dg.module.getTarget(); + try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, target)}); const rendered = buffer.toOwnedSlice(); errdefer dg.typedefs.allocator.free(rendered); @@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { if (src_val_is_undefined) return try airStoreUndefined(f, dest_ptr); + const target = f.object.dg.module.getTarget(); const writer = f.object.writer(); if (lhs_child_type.zigTypeTag() == .Array) { // For this memcpy to safely work we need the rhs to have the same // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). const rhs_type = f.air.typeOf(bin_op.rhs); - assert(rhs_type.eql(lhs_child_type)); + assert(rhs_type.eql(lhs_child_type, target)); // If the source is a constant, writeCValue will emit a brace initialization // so work around this by initializing into new local. diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 107b059765..c8ca540f59 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -812,7 +812,7 @@ pub const Object = struct { const gpa = o.gpa; // Be careful not to reference this `gop` variable after any recursive calls // to `lowerDebugType`. - const gop = try o.di_type_map.getOrPut(gpa, ty); + const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .target = o.target }); if (gop.found_existing) { const annotated = gop.value_ptr.*; const di_type = annotated.toDIType(); @@ -825,7 +825,7 @@ pub const Object = struct { }; return o.lowerDebugTypeImpl(entry, resolve, di_type); } - errdefer assert(o.di_type_map.orderedRemove(ty)); + errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target })); // The Type memory is ephemeral; since we want to store a longer-lived // reference, we need to copy it here. gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator()); @@ -856,7 +856,7 @@ pub const Object = struct { .Int => { const info = ty.intInfo(target); assert(info.bits != 0); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const dwarf_encoding: c_uint = switch (info.signedness) { .signed => DW.ATE.signed, @@ -873,7 +873,7 @@ pub const Object = struct { const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl); // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` // means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target }); return enum_di_ty; } @@ -903,7 +903,7 @@ pub const Object = struct { const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope); const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); var buffer: Type.Payload.Bits = undefined; const int_ty = ty.intTagType(&buffer); @@ -921,12 +921,12 @@ pub const Object = struct { "", ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target }); return enum_di_ty; }, .Float => { const bits = ty.floatBits(target); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const di_type = dib.createBasicType(name, bits, DW.ATE.float); gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type); @@ -974,7 +974,7 @@ pub const Object = struct { const bland_ptr_ty = Type.initPayload(&payload.base); const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .target = o.target }); return ptr_di_ty; } @@ -983,7 +983,7 @@ pub const Object = struct { const ptr_ty = ty.slicePtrFieldType(&buf); const len_ty = Type.usize; - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const di_file: ?*llvm.DIFile = null; const line = 0; @@ -1054,12 +1054,12 @@ pub const Object = struct { ); dib.replaceTemporary(fwd_decl, full_di_ty); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target }); return full_di_ty; } const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const ptr_di_ty = dib.createPointerType( elem_di_ty, @@ -1068,7 +1068,7 @@ pub const Object = struct { name, ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target }); return ptr_di_ty; }, .Opaque => { @@ -1077,7 +1077,7 @@ pub const Object = struct { gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty); return di_ty; } - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const owner_decl = ty.getOwnerDecl(); const opaque_di_ty = dib.createForwardDeclType( @@ -1089,7 +1089,7 @@ pub const Object = struct { ); // The recursive call to `lowerDebugType` va `namespaceToDebugScope` // means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .target = o.target }); return opaque_di_ty; }, .Array => { @@ -1100,7 +1100,7 @@ pub const Object = struct { @intCast(c_int, ty.arrayLen()), ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .target = o.target }); return array_di_ty; }, .Vector => { @@ -1111,11 +1111,11 @@ pub const Object = struct { ty.vectorLen(), ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .target = o.target }); return vector_di_ty; }, .Optional => { - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); var buf: Type.Payload.ElemType = undefined; const child_ty = ty.optionalChild(&buf); @@ -1127,7 +1127,7 @@ pub const Object = struct { if (ty.isPtrLikeOptional()) { const ptr_di_ty = try o.lowerDebugType(child_ty, resolve); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target }); return ptr_di_ty; } @@ -1200,7 +1200,7 @@ pub const Object = struct { ); dib.replaceTemporary(fwd_decl, full_di_ty); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target }); return full_di_ty; }, .ErrorUnion => { @@ -1209,10 +1209,10 @@ pub const Object = struct { if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .target = o.target }); return err_set_di_ty; } - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const di_file: ?*llvm.DIFile = null; const line = 0; @@ -1282,7 +1282,7 @@ pub const Object = struct { ); dib.replaceTemporary(fwd_decl, full_di_ty); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target }); return full_di_ty; }, .ErrorSet => { @@ -1294,7 +1294,7 @@ pub const Object = struct { }, .Struct => { const compile_unit_scope = o.di_compile_unit.?.toScope(); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); if (ty.castTag(.@"struct")) |payload| { @@ -1381,7 +1381,7 @@ pub const Object = struct { ); dib.replaceTemporary(fwd_decl, full_di_ty); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target }); return full_di_ty; } @@ -1395,7 +1395,7 @@ pub const Object = struct { dib.replaceTemporary(fwd_decl, struct_di_ty); // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` // means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target }); return struct_di_ty; } } @@ -1406,7 +1406,7 @@ pub const Object = struct { dib.replaceTemporary(fwd_decl, struct_di_ty); // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` // means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target }); return struct_di_ty; } @@ -1461,13 +1461,13 @@ pub const Object = struct { ); dib.replaceTemporary(fwd_decl, full_di_ty); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target }); return full_di_ty; }, .Union => { const owner_decl = ty.getOwnerDecl(); - const name = try ty.nameAlloc(gpa); + const name = try ty.nameAlloc(gpa, target); defer gpa.free(name); const fwd_decl = opt_fwd_decl orelse blk: { @@ -1489,7 +1489,7 @@ pub const Object = struct { dib.replaceTemporary(fwd_decl, union_di_ty); // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` // means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target }); return union_di_ty; } @@ -1603,7 +1603,7 @@ pub const Object = struct { 0, ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. - try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty)); + try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .target = o.target }); return fn_di_ty; }, .ComptimeInt => unreachable, @@ -1676,7 +1676,9 @@ pub const DeclGen = struct { const decl = dg.decl; assert(decl.has_tv); - log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val.fmtDebug() }); + log.debug("gen: {s} type: {}, value: {}", .{ + decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(), + }); if (decl.val.castTag(.function)) |func_payload| { _ = func_payload; @@ -1990,7 +1992,7 @@ pub const DeclGen = struct { }, .Opaque => switch (t.tag()) { .@"opaque" => { - const gop = try dg.object.type_map.getOrPut(gpa, t); + const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target }); if (gop.found_existing) return gop.value_ptr.*; // The Type memory is ephemeral; since we want to store a longer-lived @@ -2051,7 +2053,7 @@ pub const DeclGen = struct { return dg.context.intType(16); }, .Struct => { - const gop = try dg.object.type_map.getOrPut(gpa, t); + const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target }); if (gop.found_existing) return gop.value_ptr.*; // The Type memory is ephemeral; since we want to store a longer-lived @@ -2174,7 +2176,7 @@ pub const DeclGen = struct { return llvm_struct_ty; }, .Union => { - const gop = try dg.object.type_map.getOrPut(gpa, t); + const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target }); if (gop.found_existing) return gop.value_ptr.*; // The Type memory is ephemeral; since we want to store a longer-lived @@ -2289,6 +2291,7 @@ pub const DeclGen = struct { const llvm_type = try dg.llvmType(tv.ty); return llvm_type.getUndef(); } + const target = dg.module.getTarget(); switch (tv.ty.zigTypeTag()) { .Bool => { @@ -2302,8 +2305,7 @@ pub const DeclGen = struct { .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data), else => { var bigint_space: Value.BigIntSpace = undefined; - const bigint = tv.val.toBigInt(&bigint_space); - const target = dg.module.getTarget(); + const bigint = tv.val.toBigInt(&bigint_space, target); const int_info = tv.ty.intInfo(target); assert(int_info.bits != 0); const llvm_type = dg.context.intType(int_info.bits); @@ -2331,9 +2333,8 @@ pub const DeclGen = struct { const int_val = tv.enumToInt(&int_buffer); var bigint_space: Value.BigIntSpace = undefined; - const bigint = int_val.toBigInt(&bigint_space); + const bigint = int_val.toBigInt(&bigint_space, target); - const target = dg.module.getTarget(); const int_info = tv.ty.intInfo(target); const llvm_type = dg.context.intType(int_info.bits); @@ -2356,7 +2357,6 @@ pub const DeclGen = struct { }, .Float => { const llvm_ty = try dg.llvmType(tv.ty); - const target = dg.module.getTarget(); switch (tv.ty.floatBits(target)) { 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)), 80 => { @@ -2414,7 +2414,7 @@ pub const DeclGen = struct { }, .int_u64, .one, .int_big_positive => { const llvm_usize = try dg.llvmType(Type.usize); - const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(), .False); + const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False); return llvm_int.constIntToPtr(try dg.llvmType(tv.ty)); }, .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { @@ -2424,7 +2424,9 @@ pub const DeclGen = struct { const llvm_type = try dg.llvmType(tv.ty); return llvm_type.constNull(); }, - else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }), + else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ + tv.ty.fmtDebug(), tag, + }), }, .Array => switch (tv.val.tag()) { .bytes => { @@ -2592,7 +2594,6 @@ pub const DeclGen = struct { const llvm_struct_ty = try dg.llvmType(tv.ty); const field_vals = tv.val.castTag(.aggregate).?.data; const gpa = dg.gpa; - const target = dg.module.getTarget(); if (tv.ty.isTupleOrAnonStruct()) { const tuple = tv.ty.tupleFields(); @@ -2753,7 +2754,6 @@ pub const DeclGen = struct { const llvm_union_ty = try dg.llvmType(tv.ty); const tag_and_val = tv.val.castTag(.@"union").?.data; - const target = dg.module.getTarget(); const layout = tv.ty.unionGetLayout(target); if (layout.payload_size == 0) { @@ -2763,7 +2763,7 @@ pub const DeclGen = struct { }); } const union_obj = tv.ty.cast(Type.Payload.Union).?.data; - const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag).?; + const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, target).?; assert(union_obj.haveFieldTypes()); const field_ty = union_obj.fields.values()[field_index].ty; const payload = p: { @@ -2892,7 +2892,7 @@ pub const DeclGen = struct { .Frame, .AnyFrame, - => return dg.todo("implement const of type '{}'", .{tv.ty}), + => return dg.todo("implement const of type '{}'", .{tv.ty.fmtDebug()}), } } @@ -2910,7 +2910,8 @@ pub const DeclGen = struct { const ptr_ty = Type.initPayload(&ptr_ty_payload.base); const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl); - if (ptr_child_ty.eql(decl.ty)) { + const target = dg.module.getTarget(); + if (ptr_child_ty.eql(decl.ty, target)) { return llvm_ptr; } else { return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0)); @@ -2918,6 +2919,7 @@ pub const DeclGen = struct { } fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value { + const target = dg.module.getTarget(); var bitcast_needed: bool = undefined; const llvm_ptr = switch (ptr_val.tag()) { .decl_ref_mut => { @@ -2951,7 +2953,6 @@ pub const DeclGen = struct { const field_index = @intCast(u32, field_ptr.field_index); const llvm_u32 = dg.context.intType(32); - const target = dg.module.getTarget(); switch (parent_ty.zigTypeTag()) { .Union => { bitcast_needed = true; @@ -2974,7 +2975,7 @@ pub const DeclGen = struct { }, .Struct => { const field_ty = parent_ty.structFieldType(field_index); - bitcast_needed = !field_ty.eql(ptr_child_ty); + bitcast_needed = !field_ty.eql(ptr_child_ty, target); var ty_buf: Type.Payload.Pointer = undefined; const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?; @@ -2990,7 +2991,7 @@ pub const DeclGen = struct { .elem_ptr => blk: { const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty); - bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty); + bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, target); const llvm_usize = try dg.llvmType(Type.usize); const indices: [1]*const llvm.Value = .{ @@ -3004,7 +3005,7 @@ pub const DeclGen = struct { var buf: Type.Payload.ElemType = undefined; const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); - bitcast_needed = !payload_ty.eql(ptr_child_ty); + bitcast_needed = !payload_ty.eql(ptr_child_ty, target); if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) { // In this case, we represent pointer to optional the same as pointer @@ -3024,7 +3025,7 @@ pub const DeclGen = struct { const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty); const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); - bitcast_needed = !payload_ty.eql(ptr_child_ty); + bitcast_needed = !payload_ty.eql(ptr_child_ty, target); if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { // In this case, we represent pointer to error union the same as pointer @@ -3053,12 +3054,13 @@ pub const DeclGen = struct { tv: TypedValue, decl: *Module.Decl, ) Error!*const llvm.Value { + const target = self.module.getTarget(); if (tv.ty.isSlice()) { var buf: Type.SlicePtrFieldTypeBuffer = undefined; const ptr_ty = tv.ty.slicePtrFieldType(&buf); var slice_len: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, - .data = tv.val.sliceLen(), + .data = tv.val.sliceLen(target), }; const fields: [2]*const llvm.Value = .{ try self.genTypedValue(.{ diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 0d9d1ae223..6072c59845 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -313,7 +313,7 @@ pub const DeclGen = struct { // As of yet, there is no vector support in the self-hosted compiler. .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), // TODO: For which types is this the case? - else => self.todo("implement arithmeticTypeInfo for {}", .{ty}), + else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmtDebug()}), }; } @@ -335,7 +335,7 @@ pub const DeclGen = struct { const int_info = ty.intInfo(target); const backing_bits = self.backingIntBits(int_info.bits) orelse { // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits. - return self.todo("implement composite int constants for {}", .{ty}); + return self.todo("implement composite int constants for {}", .{ty.fmtDebug()}); }; // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any @@ -345,7 +345,7 @@ pub const DeclGen = struct { // Note, value is required to be sign-extended, so we don't need to mask off the upper bits. // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal - var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(); + var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(target); const value: spec.LiteralContextDependentNumber = switch (backing_bits) { 1...32 => .{ .uint32 = @truncate(u32, int_bits) }, @@ -388,7 +388,7 @@ pub const DeclGen = struct { }); }, .Void => unreachable, - else => return self.todo("constant generation of type {}", .{ty}), + else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}), } return result_id.toRef(); @@ -414,7 +414,7 @@ pub const DeclGen = struct { const backing_bits = self.backingIntBits(int_info.bits) orelse { // TODO: Integers too big for any native type are represented as "composite integers": // An array of largestSupportedIntBits. - return self.todo("Implement composite int type {}", .{ty}); + return self.todo("Implement composite int type {}", .{ty.fmtDebug()}); }; const payload = try self.spv.arena.create(SpvType.Payload.Int); @@ -644,8 +644,10 @@ pub const DeclGen = struct { const result_id = self.spv.allocId(); const result_type_id = try self.resolveTypeId(ty); - assert(self.air.typeOf(bin_op.lhs).eql(ty)); - assert(self.air.typeOf(bin_op.rhs).eql(ty)); + const target = self.getTarget(); + + assert(self.air.typeOf(bin_op.lhs).eql(ty, target)); + assert(self.air.typeOf(bin_op.rhs).eql(ty, target)); // Binary operations are generally applicable to both scalar and vector operations // in SPIR-V, but int and float versions of operations require different opcodes. @@ -692,7 +694,7 @@ pub const DeclGen = struct { const result_id = self.spv.allocId(); const result_type_id = try self.resolveTypeId(Type.initTag(.bool)); const op_ty = self.air.typeOf(bin_op.lhs); - assert(op_ty.eql(self.air.typeOf(bin_op.rhs))); + assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.getTarget())); // Comparisons are generally applicable to both scalar and vector operations in SPIR-V, // but int and float versions of operations require different opcodes. |
