authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-04 13:56:17-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 14:44:41-04:00
logf2f770fdd3818d1ec14e51ce752aca5beb08e150
treedcf49a573dde69f7978527e2a80627152cca3fd8
parent703baa4cd662e55ba39ea14ae2f30209e7ff023b

llvm: implement c abi for x86


9 files changed, 315 insertions(+), 33 deletions(-)

lib/std/Target.zig+3-6
......@@ -1797,6 +1797,7 @@ pub const Cpu = struct {
17971797
17981798 .x86_sysv,
17991799 .x86_win,
1800 .x86_mingw,
18001801 .x86_stdcall,
18011802 .x86_fastcall,
18021803 .x86_thiscall,
......@@ -3664,18 +3665,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {
36643665pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention {
36653666 return switch (target.cpu.arch) {
36663667 .x86_64 => switch (target.os.tag) {
3667 .windows,
3668 .uefi,
3669 => .{ .x86_64_win = .{} },
3668 .windows, .uefi => .{ .x86_64_win = .{} },
36703669 else => switch (target.abi) {
36713670 .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} },
36723671 else => .{ .x86_64_sysv = .{} },
36733672 },
36743673 },
36753674 .x86 => switch (target.os.tag) {
3676 .windows,
3677 .uefi,
3678 => .{ .x86_win = .{} },
3675 .windows, .uefi => if (target.isMinGW()) .{ .x86_mingw = .{} } else .{ .x86_win = .{} },
36793676 else => .{ .x86_sysv = .{} },
36803677 },
36813678 .x86_16 => .{ .x86_16_cdecl = .{} },
lib/std/lang.zig+1
......@@ -214,6 +214,7 @@ pub const CallingConvention = union(enum(u8)) {
214214 // Calling conventions for the `x86` architecture.
215215 x86_sysv: X86RegparmOptions,
216216 x86_win: X86RegparmOptions,
217 x86_mingw: X86RegparmOptions,
217218 x86_stdcall: X86RegparmOptions,
218219 x86_fastcall: CommonOptions,
219220 x86_thiscall: CommonOptions,
src/Sema.zig+1
......@@ -8501,6 +8501,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta
85018501 .x86_64_win,
85028502 .x86_sysv,
85038503 .x86_win,
8504 .x86_mingw,
85048505 .aarch64_aapcs,
85058506 .aarch64_aapcs_darwin,
85068507 .aarch64_aapcs_win,
src/Zcu.zig+2
......@@ -4644,6 +4644,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
46444644
46454645 .x86_sysv,
46464646 .x86_win,
4647 .x86_mingw,
46474648 .x86_stdcall,
46484649 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,
46494650
......@@ -4678,6 +4679,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
46784679 .stage2_x86 => switch (cc) {
46794680 .x86_sysv,
46804681 .x86_win,
4682 .x86_mingw,
46814683 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,
46824684 .naked => true,
46834685 else => false,
src/codegen.zig+195
......@@ -1124,6 +1124,201 @@ pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu:
11241124 };
11251125}
11261126
1127pub const FlattenedItem = struct { offset: u64, type: ?Type };
1128pub fn flattenType(items_buf: []FlattenedItem, ty: Type, zcu: *Zcu, opts: struct {
1129 offset: u64 = 0,
1130 allow_arrays: bool = true,
1131 fn increaseOffset(opts: @This(), offset: u64) @This() {
1132 return .{
1133 .offset = opts.offset + offset,
1134 .allow_arrays = opts.allow_arrays,
1135 };
1136 }
1137}) ?[]FlattenedItem {
1138 const ip = &zcu.intern_pool;
1139 switch (ip.indexToKey(ty.toIntern())) {
1140 .int_type => |int_type| {
1141 if (int_type.bits == 0) return items_buf[0..0];
1142 if (items_buf.len < 1) return null;
1143 const items = items_buf[0..1];
1144 items.* = .{.{ .offset = opts.offset, .type = ty }};
1145 return items;
1146 },
1147 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1148 .one, .many, .c => {
1149 if (items_buf.len < 1) return null;
1150 const items = items_buf[0..1];
1151 items.* = .{.{ .offset = opts.offset, .type = ty }};
1152 return items;
1153 },
1154 .slice => {
1155 if (items_buf.len < 2) return null;
1156 const items = items_buf[0..2];
1157 const ptr_field_ty = ty.slicePtrFieldType(zcu);
1158 items.* = .{
1159 .{ .offset = opts.offset, .type = ptr_field_ty },
1160 .{ .offset = opts.offset + ptr_field_ty.abiSize(zcu), .type = .usize },
1161 };
1162 return items;
1163 },
1164 },
1165 .array_type => |array_type| {
1166 const len = array_type.lenIncludingSentinel();
1167 if (len == 0) return items_buf[0..0];
1168 const elem_ty: Type = .fromInterned(array_type.child);
1169 const elem_items = flattenType(items_buf, elem_ty, zcu, opts) orelse return null;
1170 if (elem_items.len == 0) return items_buf[0..0];
1171 if (!opts.allow_arrays) return null;
1172 const items_len, const items_overflow = @mulWithOverflow(elem_items.len, len);
1173 if (items_overflow != 0 or items_buf.len < items_len) return null;
1174 var items_index = elem_items.len;
1175 const elem_size = elem_ty.abiSize(zcu);
1176 var elem_offset: u64 = elem_size;
1177 while (items_index != items_len) : ({
1178 items_index += elem_items.len;
1179 elem_offset += elem_size;
1180 }) for (items_buf[items_index..][0..elem_items.len], elem_items) |*item, elem_item| {
1181 item.* = .{ .offset = elem_offset + elem_item.offset, .type = elem_item.type };
1182 };
1183 return items_buf[0..@intCast(items_len)];
1184 },
1185 .vector_type => |vector_type| {
1186 if (vector_type.len == 0) return items_buf[0..0];
1187 if (items_buf.len < 1) return null;
1188 const items = items_buf[0..1];
1189 items.* = .{.{ .offset = opts.offset, .type = ty }};
1190 return items;
1191 },
1192 .opt_type, .error_union_type => return null,
1193 .simple_type => |simple_type| switch (simple_type) {
1194 .f16,
1195 .f32,
1196 .f64,
1197 .f80,
1198 .f128,
1199 .usize,
1200 .isize,
1201 .c_char,
1202 .c_short,
1203 .c_ushort,
1204 .c_int,
1205 .c_uint,
1206 .c_long,
1207 .c_ulong,
1208 .c_longlong,
1209 .c_ulonglong,
1210 .c_longdouble,
1211 .bool,
1212 .anyerror,
1213 => {
1214 if (items_buf.len < 1) return null;
1215 const items = items_buf[0..1];
1216 items.* = .{.{ .offset = opts.offset, .type = ty }};
1217 return items;
1218 },
1219 .anyopaque, .noreturn => return null,
1220 .void,
1221 .type,
1222 .comptime_int,
1223 .comptime_float,
1224 .null,
1225 .undefined,
1226 .enum_literal,
1227 => return items_buf[0..0],
1228 .adhoc_inferred_error_set, .generic_poison => unreachable,
1229 },
1230 .struct_type => {
1231 const loaded_struct = ip.loadStructType(ty.toIntern());
1232 switch (loaded_struct.layout) {
1233 .auto, .@"extern" => {},
1234 .@"packed" => return flattenType(items_buf, .fromInterned(
1235 loaded_struct.packed_backing_int_type,
1236 ), zcu, opts),
1237 }
1238 var items_len: usize = 0;
1239 var offset: u64 = 0;
1240 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1241 while (field_it.next()) |field_index| {
1242 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1243 const field_offset = loaded_struct.field_offsets.get(ip)[field_index];
1244 if (field_offset - offset > 0 and
1245 (items_len == 0 or items_buf[items_len - 1].type != null))
1246 {
1247 if (items_len == items_buf.len) return null;
1248 items_buf[items_len] = .{ .offset = offset, .type = null };
1249 items_len += 1;
1250 }
1251 items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset(
1252 field_offset,
1253 )) orelse return null).len;
1254 offset = field_offset + field_ty.abiSize(zcu);
1255 }
1256 if (ty.abiSize(zcu) - offset > 0 and
1257 (items_len == 0 or items_buf[items_len - 1].type != null))
1258 {
1259 if (items_len == items_buf.len) return null;
1260 items_buf[items_len] = .{ .offset = offset, .type = null };
1261 items_len += 1;
1262 }
1263 return items_buf[0..items_len];
1264 },
1265 .tuple_type => |tuple_type| {
1266 if (items_buf.len < tuple_type.types.len) return null;
1267 var items_len: usize = 0;
1268 var offset: u64 = 0;
1269 for (tuple_type.types.get(ip)) |field_ty_ip| {
1270 const field_ty: Type = .fromInterned(field_ty_ip);
1271 offset = field_ty.abiAlignment(zcu).forward(offset);
1272 items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset(
1273 offset,
1274 )) orelse return null).len;
1275 offset += field_ty.abiSize(zcu);
1276 }
1277 return items_buf[0..items_len];
1278 },
1279 .union_type => {
1280 const loaded_union = ip.loadUnionType(ty.toIntern());
1281 return switch (loaded_union.layout) {
1282 .auto, .@"extern" => return null,
1283 .@"packed" => return flattenType(items_buf, .fromInterned(
1284 loaded_union.packed_backing_int_type,
1285 ), zcu, opts),
1286 };
1287 },
1288 .opaque_type, .spirv_type, .func_type => return null,
1289 .enum_type => return flattenType(items_buf, .fromInterned(
1290 ip.loadEnumType(ty.toIntern()).int_tag_type,
1291 ), zcu, opts),
1292 .error_set_type, .inferred_error_set_type => {
1293 if (items_buf.len < 1) return null;
1294 const items = items_buf[0..1];
1295 items.* = .{.{ .offset = opts.offset, .type = ty }};
1296 return items;
1297 },
1298 .anyframe_type,
1299 // values, not types
1300 .undef,
1301 .simple_value,
1302 .@"extern",
1303 .func,
1304 .int,
1305 .err,
1306 .error_union,
1307 .enum_literal,
1308 .enum_tag,
1309 .float,
1310 .ptr,
1311 .slice,
1312 .opt,
1313 .aggregate,
1314 .un,
1315 .bitpack,
1316 // memoization, not types
1317 .memoized_call,
1318 => unreachable,
1319 }
1320}
1321
11271322test {
11281323 _ = aarch64;
11291324}
src/codegen/c.zig+1-1
......@@ -7289,7 +7289,7 @@ fn toCallingConvention(cc: std.lang.CallingConvention, zcu: *Zcu) ?[]const u8 {
72897289 .x86_16_cdecl => "cdecl",
72907290 .x86_16_regparmcall => "regparmcall",
72917291 .x86_64_sysv, .x86_sysv => "sysv_abi",
7292 .x86_64_win, .x86_win => "ms_abi",
7292 .x86_64_win, .x86_win, .x86_mingw => "ms_abi",
72937293 .x86_16_stdcall, .x86_stdcall => "stdcall",
72947294 .x86_fastcall => "fastcall",
72957295 .x86_thiscall => "thiscall",
src/codegen/llvm.zig+13-5
......@@ -4235,19 +4235,26 @@ pub const Object = struct {
42354235 };
42364236 }
42374237
4238 pub const Byval = struct { alignment: InternPool.Alignment = .none };
42384239 pub fn addByRefParamAttrs(
42394240 o: *Object,
42404241 attributes: *Builder.FunctionAttributes.Wip,
42414242 llvm_arg_i: u32,
4242 byval: bool,
4243 maybe_byval: ?Byval,
42434244 param_ty: Type,
42444245 ) Allocator.Error!void {
42454246 const llvm_param_ty = try o.lowerType(param_ty, .in_memory);
4246 const alignment = param_ty.abiAlignment(o.zcu).toLlvm();
4247 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
42484247 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4249 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(alignment) }, &o.builder);
4250 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder);
4248 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
4249 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
4250 const alignment = if (maybe_byval) |byval| alignment: {
4251 try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder);
4252 break :alignment byval.alignment;
4253 } else .none;
4254 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(switch (alignment) {
4255 .none => param_ty.abiAlignment(o.zcu),
4256 else => alignment,
4257 }.toLlvm()) }, &o.builder);
42514258 }
42524259
42534260 pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index {
......@@ -4598,6 +4605,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const
45984605 .x86_16_interrupt,
45994606 .x86_sysv,
46004607 .x86_win,
4608 .x86_mingw,
46014609 .x86_thiscall_mingw,
46024610 .x86_64_x32,
46034611 .aarch64_aapcs,
src/codegen/llvm/FuncGen.zig+98-19
......@@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
218218 switch (lowering) {
219219 .no_bits => continue,
220220 .byval => {
221 assert(!it.byval_attr);
221 assert(it.byval_attr == null);
222222 const param_index = it.zig_index - 1;
223223 const param_ty: Type = .fromInterned(param_types[param_index]);
224224 const param = fg.wip.arg(it.llvm_index - 1);
......@@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
237237 .byref, .byref_mut => {
238238 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
239239 const param = fg.wip.arg(it.llvm_index - 1);
240 const alignment = if (it.byval_attr) |byval_attr| byval_attr.alignment else .none;
240241
241 if (isByRef(param_ty, zcu)) {
242 if (alignment == .none and isByRef(param_ty, zcu)) {
242243 args.appendAssumeCapacity(param);
243244 } else {
244 args.appendAssumeCapacity(try fg.load(param, .none, param_ty, .normal));
245 args.appendAssumeCapacity(try fg.load(param, alignment, param_ty, .normal));
245246 }
246247 },
247248 .abi_sized_int => {
248 assert(!it.byval_attr);
249 assert(it.byval_attr == null);
249250 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
250251 const param = fg.wip.arg(it.llvm_index - 1);
251252
......@@ -260,7 +261,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
260261 }
261262 },
262263 .slice => {
263 assert(!it.byval_attr);
264 assert(it.byval_attr == null);
264265 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
265266 assert(!isByRef(param_ty, zcu));
266267 const slice_val = try fg.wip.buildAggregate(
......@@ -271,7 +272,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void {
271272 args.appendAssumeCapacity(slice_val);
272273 },
273274 .multiple_llvm_types => {
274 assert(!it.byval_attr);
275 assert(it.byval_attr == null);
275276 const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]);
276277 const param_alignment = param_ty.abiAlignment(zcu);
277278 const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8);
......@@ -963,7 +964,7 @@ fn buildCall(
963964 => continue,
964965
965966 .slice => {
966 assert(!it.byval_attr);
967 assert(it.byval_attr == null);
967968 const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]);
968969 const ptr_info = param_ty.ptrInfo(zcu);
969970 const llvm_arg_i = it.llvm_index - 2;
......@@ -6913,7 +6914,7 @@ const ParamTypeIterator = struct {
69136914 types_len: u32,
69146915 types_buffer: [8]Builder.Type,
69156916 offsets_buffer: [9]u64,
6916 byval_attr: bool,
6917 byval_attr: ?Object.Byval,
69176918
69186919 const Lowering = union(enum) {
69196920 no_bits,
......@@ -6931,7 +6932,7 @@ const ParamTypeIterator = struct {
69316932 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
69326933 if (it.zig_index >= it.param_types.len) return null;
69336934 const ty = it.param_types[it.zig_index];
6934 it.byval_attr = false;
6935 it.byval_attr = null;
69356936 return nextInner(it, Type.fromInterned(ty));
69366937 }
69376938
......@@ -7008,7 +7009,7 @@ const ParamTypeIterator = struct {
70087009 it.llvm_index += 1;
70097010 switch (arm_c_abi.classifyType(ty, zcu, .arg)) {
70107011 .memory => {
7011 it.byval_attr = true;
7012 it.byval_attr = .{};
70127013 return .byref;
70137014 },
70147015 .byval => return .byval,
......@@ -7086,7 +7087,7 @@ const ParamTypeIterator = struct {
70867087 it.llvm_index += 1;
70877088 switch (mips_c_abi.classifyType(ty, zcu, .arg)) {
70887089 .memory => {
7089 it.byval_attr = true;
7090 it.byval_attr = .{};
70907091 return .byref;
70917092 },
70927093 .byval => return .byval,
......@@ -7158,15 +7159,15 @@ const ParamTypeIterator = struct {
71587159 it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .as_value)};
71597160 it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) };
71607161 it.types_len = 1;
7161 it.llvm_index += 1;
71627162 it.zig_index += 1;
7163 it.llvm_index += 1;
71637164 return .multiple_llvm_types;
71647165 }
71657166 },
71667167 .indirect => {
71677168 it.zig_index += 1;
71687169 it.llvm_index += 1;
7169 it.byval_attr = true;
7170 it.byval_attr = .{};
71707171 return .byref;
71717172 },
71727173 },
......@@ -7177,9 +7178,55 @@ const ParamTypeIterator = struct {
71777178 if (isScalar(zcu, ty)) {
71787179 return .byval;
71797180 } else {
7180 it.byval_attr = true;
7181 it.byval_attr = .{};
7182 return .byref;
7183 }
7184 },
7185 .x86_sysv, .x86_win, .x86_mingw => {
7186 if (isByRef(ty, zcu)) {
7187 var items_buf: [1]codegen.FlattenedItem = undefined;
7188 if (codegen.flattenType(&items_buf, ty, zcu, .{
7189 .allow_arrays = false,
7190 })) |items| one_float: {
7191 if (items.len != 1 or items[0].offset != 0) break :one_float;
7192 const item_ty = items[0].type orelse break :one_float;
7193 if (!item_ty.isRuntimeFloat()) break :one_float;
7194 it.types_buffer[0..1].*, it.offsets_buffer[0..2].* =
7195 switch (item_ty.floatBits(zcu.getTarget())) {
7196 else => unreachable,
7197 32 => .{ .{.float}, .{ 0, 4 } },
7198 64 => .{ .{.double}, .{ 0, 8 } },
7199 16, 80, 128 => break :one_float,
7200 };
7201 it.types_len = 1;
7202 it.zig_index += 1;
7203 it.llvm_index += 1;
7204 return .multiple_llvm_types;
7205 }
7206 it.zig_index += 1;
7207 it.llvm_index += 1;
7208 it.byval_attr = .{ .alignment = .@"4" };
71817209 return .byref;
71827210 }
7211 if (ty.isAbiInt(zcu)) switch (ty.intInfo(zcu).bits) {
7212 else => unreachable,
7213 8, 16, 32, 64 => {
7214 it.zig_index += 1;
7215 it.llvm_index += 1;
7216 return .byval;
7217 },
7218 128 => {
7219 it.types_buffer[0..2].* = .{ .i64, .i64 };
7220 it.offsets_buffer[0..3].* = .{ 0, 8, 16 };
7221 it.types_len = 2;
7222 it.zig_index += 1;
7223 it.llvm_index += 2;
7224 return .multiple_llvm_types;
7225 },
7226 };
7227 it.zig_index += 1;
7228 it.llvm_index += 1;
7229 return .byval;
71837230 },
71847231 .x86_64_sysv, .x86_64_x32 => return try it.next_x86_64_sysv(ty),
71857232 .x86_64_win => return it.next_x86_64_win(ty),
......@@ -7277,7 +7324,7 @@ const ParamTypeIterator = struct {
72777324 .x87 => {
72787325 it.zig_index += 1;
72797326 it.llvm_index += 1;
7280 it.byval_attr = true;
7327 it.byval_attr = .{};
72817328 return .byref;
72827329 },
72837330 .x87up => unreachable,
......@@ -7285,7 +7332,7 @@ const ParamTypeIterator = struct {
72857332 .memory => {
72867333 it.zig_index += 1;
72877334 it.llvm_index += 1;
7288 it.byval_attr = true;
7335 it.byval_attr = .{};
72897336 return .byref;
72907337 },
72917338 .win_i128 => unreachable, // windows only
......@@ -7306,7 +7353,7 @@ const ParamTypeIterator = struct {
73067353 if (it.llvm_index + classes_len > 6) {
73077354 it.zig_index += 1;
73087355 it.llvm_index += 1;
7309 it.byval_attr = true;
7356 it.byval_attr = .{};
73107357 return .byref;
73117358 }
73127359 } else if (!isByRef(ty, zcu)) {
......@@ -7340,7 +7387,7 @@ pub fn iterateParamTypes(
73407387 .types_len = undefined,
73417388 .types_buffer = undefined,
73427389 .offsets_buffer = undefined,
7343 .byval_attr = false,
7390 .byval_attr = null,
73447391 };
73457392}
73467393
......@@ -7466,7 +7513,39 @@ pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) A
74667513 return .by_val;
74677514 } else .sret,
74687515 .x86_fastcall => fnReturnStrat_x86_fastcall(o, zcu, ret_ty),
7469 .x86_sysv, .x86_win => if (isByRef(ret_ty, zcu)) .sret else .by_val,
7516 .x86_sysv, .x86_win, .x86_mingw => if (isByRef(ret_ty, zcu)) {
7517 switch (cc) {
7518 else => unreachable,
7519 .x86_sysv => return .sret,
7520 .x86_win => {},
7521 .x86_mingw => {
7522 var items_buf: [1]codegen.FlattenedItem = undefined;
7523 if (codegen.flattenType(&items_buf, ret_ty, zcu, .{})) |items| one_float: {
7524 if (items.len != 1 or items[0].offset != 0) break :one_float;
7525 const item_ty = items[0].type orelse break :one_float;
7526 if (!item_ty.isRuntimeFloat()) break :one_float;
7527 return .{ .mem_cast = switch (item_ty.floatBits(zcu.getTarget())) {
7528 else => unreachable,
7529 16 => .half,
7530 32 => .float,
7531 64 => .double,
7532 80, 128 => break :one_float,
7533 } };
7534 }
7535 },
7536 }
7537 return switch (ret_ty.abiSize(zcu)) {
7538 0 => .void,
7539 1 => .{ .mem_cast = .i8 },
7540 2 => .{ .mem_cast = .i16 },
7541 4 => .{ .mem_cast = .i32 },
7542 8 => .{ .mem_cast = .i64 },
7543 else => .sret,
7544 };
7545 } else if (ret_ty.isAbiInt(zcu) and ret_ty.intInfo(zcu).bits > 64)
7546 .sret
7547 else
7548 .by_val,
74707549 .x86_64_sysv, .x86_64_x32 => fnReturnStrat_x86_64_sysv(o, ret_ty),
74717550 .x86_64_win => fnReturnStrat_x86_64_win(o, ret_ty),
74727551 // TODO investigate other callconvs
src/link/Dwarf.zig+1-2
......@@ -4151,8 +4151,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
41514151 .x86_64_regcall_v3_sysv => .LLVM_X86RegCall,
41524152 .x86_64_regcall_v4_win => .LLVM_X86RegCall,
41534153 .x86_64_vectorcall => .LLVM_vectorcall,
4154 .x86_sysv => .normal,
4155 .x86_win => .normal,
4154 .x86_sysv, .x86_win, .x86_mingw => .normal,
41564155 .x86_stdcall => .BORLAND_stdcall,
41574156 .x86_fastcall => .BORLAND_msfastcall,
41584157 .x86_thiscall => .BORLAND_thiscall,