| author | |
| committer | |
| log | f2f770fdd3818d1ec14e51ce752aca5beb08e150 |
| tree | dcf49a573dde69f7978527e2a80627152cca3fd8 |
| parent | 703baa4cd662e55ba39ea14ae2f30209e7ff023b |
9 files changed, 315 insertions(+), 33 deletions(-)
lib/std/Target.zig+3-6| ... | ... | @@ -1797,6 +1797,7 @@ pub const Cpu = struct { |
| 1797 | 1797 | |
| 1798 | 1798 | .x86_sysv, |
| 1799 | 1799 | .x86_win, |
| 1800 | .x86_mingw, | |
| 1800 | 1801 | .x86_stdcall, |
| 1801 | 1802 | .x86_fastcall, |
| 1802 | 1803 | .x86_thiscall, |
| ... | ... | @@ -3664,18 +3665,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { |
| 3664 | 3665 | pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention { |
| 3665 | 3666 | return switch (target.cpu.arch) { |
| 3666 | 3667 | .x86_64 => switch (target.os.tag) { |
| 3667 | .windows, | |
| 3668 | .uefi, | |
| 3669 | => .{ .x86_64_win = .{} }, | |
| 3668 | .windows, .uefi => .{ .x86_64_win = .{} }, | |
| 3670 | 3669 | else => switch (target.abi) { |
| 3671 | 3670 | .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} }, |
| 3672 | 3671 | else => .{ .x86_64_sysv = .{} }, |
| 3673 | 3672 | }, |
| 3674 | 3673 | }, |
| 3675 | 3674 | .x86 => switch (target.os.tag) { |
| 3676 | .windows, | |
| 3677 | .uefi, | |
| 3678 | => .{ .x86_win = .{} }, | |
| 3675 | .windows, .uefi => if (target.isMinGW()) .{ .x86_mingw = .{} } else .{ .x86_win = .{} }, | |
| 3679 | 3676 | else => .{ .x86_sysv = .{} }, |
| 3680 | 3677 | }, |
| 3681 | 3678 | .x86_16 => .{ .x86_16_cdecl = .{} }, |
lib/std/lang.zig+1| ... | ... | @@ -214,6 +214,7 @@ pub const CallingConvention = union(enum(u8)) { |
| 214 | 214 | // Calling conventions for the `x86` architecture. |
| 215 | 215 | x86_sysv: X86RegparmOptions, |
| 216 | 216 | x86_win: X86RegparmOptions, |
| 217 | x86_mingw: X86RegparmOptions, | |
| 217 | 218 | x86_stdcall: X86RegparmOptions, |
| 218 | 219 | x86_fastcall: CommonOptions, |
| 219 | 220 | x86_thiscall: CommonOptions, |
src/Sema.zig+1| ... | ... | @@ -8501,6 +8501,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta |
| 8501 | 8501 | .x86_64_win, |
| 8502 | 8502 | .x86_sysv, |
| 8503 | 8503 | .x86_win, |
| 8504 | .x86_mingw, | |
| 8504 | 8505 | .aarch64_aapcs, |
| 8505 | 8506 | .aarch64_aapcs_darwin, |
| 8506 | 8507 | .aarch64_aapcs_win, |
src/Zcu.zig+2| ... | ... | @@ -4644,6 +4644,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4644 | 4644 | |
| 4645 | 4645 | .x86_sysv, |
| 4646 | 4646 | .x86_win, |
| 4647 | .x86_mingw, | |
| 4647 | 4648 | .x86_stdcall, |
| 4648 | 4649 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, |
| 4649 | 4650 | |
| ... | ... | @@ -4678,6 +4679,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4678 | 4679 | .stage2_x86 => switch (cc) { |
| 4679 | 4680 | .x86_sysv, |
| 4680 | 4681 | .x86_win, |
| 4682 | .x86_mingw, | |
| 4681 | 4683 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, |
| 4682 | 4684 | .naked => true, |
| 4683 | 4685 | 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: |
| 1124 | 1124 | }; |
| 1125 | 1125 | } |
| 1126 | 1126 | |
| 1127 | pub const FlattenedItem = struct { offset: u64, type: ?Type }; | |
| 1128 | pub 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 | ||
| 1127 | 1322 | test { |
| 1128 | 1323 | _ = aarch64; |
| 1129 | 1324 | } |
src/codegen/c.zig+1-1| ... | ... | @@ -7289,7 +7289,7 @@ fn toCallingConvention(cc: std.lang.CallingConvention, zcu: *Zcu) ?[]const u8 { |
| 7289 | 7289 | .x86_16_cdecl => "cdecl", |
| 7290 | 7290 | .x86_16_regparmcall => "regparmcall", |
| 7291 | 7291 | .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", | |
| 7293 | 7293 | .x86_16_stdcall, .x86_stdcall => "stdcall", |
| 7294 | 7294 | .x86_fastcall => "fastcall", |
| 7295 | 7295 | .x86_thiscall => "thiscall", |
src/codegen/llvm.zig+13-5| ... | ... | @@ -4235,19 +4235,26 @@ pub const Object = struct { |
| 4235 | 4235 | }; |
| 4236 | 4236 | } |
| 4237 | 4237 | |
| 4238 | pub const Byval = struct { alignment: InternPool.Alignment = .none }; | |
| 4238 | 4239 | pub fn addByRefParamAttrs( |
| 4239 | 4240 | o: *Object, |
| 4240 | 4241 | attributes: *Builder.FunctionAttributes.Wip, |
| 4241 | 4242 | llvm_arg_i: u32, |
| 4242 | byval: bool, | |
| 4243 | maybe_byval: ?Byval, | |
| 4243 | 4244 | param_ty: Type, |
| 4244 | 4245 | ) Allocator.Error!void { |
| 4245 | 4246 | 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); | |
| 4248 | 4247 | 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); | |
| 4251 | 4258 | } |
| 4252 | 4259 | |
| 4253 | 4260 | 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 |
| 4598 | 4605 | .x86_16_interrupt, |
| 4599 | 4606 | .x86_sysv, |
| 4600 | 4607 | .x86_win, |
| 4608 | .x86_mingw, | |
| 4601 | 4609 | .x86_thiscall_mingw, |
| 4602 | 4610 | .x86_64_x32, |
| 4603 | 4611 | .aarch64_aapcs, |
src/codegen/llvm/FuncGen.zig+98-19| ... | ... | @@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 218 | 218 | switch (lowering) { |
| 219 | 219 | .no_bits => continue, |
| 220 | 220 | .byval => { |
| 221 | assert(!it.byval_attr); | |
| 221 | assert(it.byval_attr == null); | |
| 222 | 222 | const param_index = it.zig_index - 1; |
| 223 | 223 | const param_ty: Type = .fromInterned(param_types[param_index]); |
| 224 | 224 | const param = fg.wip.arg(it.llvm_index - 1); |
| ... | ... | @@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 237 | 237 | .byref, .byref_mut => { |
| 238 | 238 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 239 | 239 | const param = fg.wip.arg(it.llvm_index - 1); |
| 240 | const alignment = if (it.byval_attr) |byval_attr| byval_attr.alignment else .none; | |
| 240 | 241 | |
| 241 | if (isByRef(param_ty, zcu)) { | |
| 242 | if (alignment == .none and isByRef(param_ty, zcu)) { | |
| 242 | 243 | args.appendAssumeCapacity(param); |
| 243 | 244 | } else { |
| 244 | args.appendAssumeCapacity(try fg.load(param, .none, param_ty, .normal)); | |
| 245 | args.appendAssumeCapacity(try fg.load(param, alignment, param_ty, .normal)); | |
| 245 | 246 | } |
| 246 | 247 | }, |
| 247 | 248 | .abi_sized_int => { |
| 248 | assert(!it.byval_attr); | |
| 249 | assert(it.byval_attr == null); | |
| 249 | 250 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 250 | 251 | const param = fg.wip.arg(it.llvm_index - 1); |
| 251 | 252 | |
| ... | ... | @@ -260,7 +261,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 260 | 261 | } |
| 261 | 262 | }, |
| 262 | 263 | .slice => { |
| 263 | assert(!it.byval_attr); | |
| 264 | assert(it.byval_attr == null); | |
| 264 | 265 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 265 | 266 | assert(!isByRef(param_ty, zcu)); |
| 266 | 267 | const slice_val = try fg.wip.buildAggregate( |
| ... | ... | @@ -271,7 +272,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 271 | 272 | args.appendAssumeCapacity(slice_val); |
| 272 | 273 | }, |
| 273 | 274 | .multiple_llvm_types => { |
| 274 | assert(!it.byval_attr); | |
| 275 | assert(it.byval_attr == null); | |
| 275 | 276 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 276 | 277 | const param_alignment = param_ty.abiAlignment(zcu); |
| 277 | 278 | const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8); |
| ... | ... | @@ -963,7 +964,7 @@ fn buildCall( |
| 963 | 964 | => continue, |
| 964 | 965 | |
| 965 | 966 | .slice => { |
| 966 | assert(!it.byval_attr); | |
| 967 | assert(it.byval_attr == null); | |
| 967 | 968 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 968 | 969 | const ptr_info = param_ty.ptrInfo(zcu); |
| 969 | 970 | const llvm_arg_i = it.llvm_index - 2; |
| ... | ... | @@ -6913,7 +6914,7 @@ const ParamTypeIterator = struct { |
| 6913 | 6914 | types_len: u32, |
| 6914 | 6915 | types_buffer: [8]Builder.Type, |
| 6915 | 6916 | offsets_buffer: [9]u64, |
| 6916 | byval_attr: bool, | |
| 6917 | byval_attr: ?Object.Byval, | |
| 6917 | 6918 | |
| 6918 | 6919 | const Lowering = union(enum) { |
| 6919 | 6920 | no_bits, |
| ... | ... | @@ -6931,7 +6932,7 @@ const ParamTypeIterator = struct { |
| 6931 | 6932 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { |
| 6932 | 6933 | if (it.zig_index >= it.param_types.len) return null; |
| 6933 | 6934 | const ty = it.param_types[it.zig_index]; |
| 6934 | it.byval_attr = false; | |
| 6935 | it.byval_attr = null; | |
| 6935 | 6936 | return nextInner(it, Type.fromInterned(ty)); |
| 6936 | 6937 | } |
| 6937 | 6938 | |
| ... | ... | @@ -7008,7 +7009,7 @@ const ParamTypeIterator = struct { |
| 7008 | 7009 | it.llvm_index += 1; |
| 7009 | 7010 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { |
| 7010 | 7011 | .memory => { |
| 7011 | it.byval_attr = true; | |
| 7012 | it.byval_attr = .{}; | |
| 7012 | 7013 | return .byref; |
| 7013 | 7014 | }, |
| 7014 | 7015 | .byval => return .byval, |
| ... | ... | @@ -7086,7 +7087,7 @@ const ParamTypeIterator = struct { |
| 7086 | 7087 | it.llvm_index += 1; |
| 7087 | 7088 | switch (mips_c_abi.classifyType(ty, zcu, .arg)) { |
| 7088 | 7089 | .memory => { |
| 7089 | it.byval_attr = true; | |
| 7090 | it.byval_attr = .{}; | |
| 7090 | 7091 | return .byref; |
| 7091 | 7092 | }, |
| 7092 | 7093 | .byval => return .byval, |
| ... | ... | @@ -7158,15 +7159,15 @@ const ParamTypeIterator = struct { |
| 7158 | 7159 | it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .as_value)}; |
| 7159 | 7160 | it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) }; |
| 7160 | 7161 | it.types_len = 1; |
| 7161 | it.llvm_index += 1; | |
| 7162 | 7162 | it.zig_index += 1; |
| 7163 | it.llvm_index += 1; | |
| 7163 | 7164 | return .multiple_llvm_types; |
| 7164 | 7165 | } |
| 7165 | 7166 | }, |
| 7166 | 7167 | .indirect => { |
| 7167 | 7168 | it.zig_index += 1; |
| 7168 | 7169 | it.llvm_index += 1; |
| 7169 | it.byval_attr = true; | |
| 7170 | it.byval_attr = .{}; | |
| 7170 | 7171 | return .byref; |
| 7171 | 7172 | }, |
| 7172 | 7173 | }, |
| ... | ... | @@ -7177,9 +7178,55 @@ const ParamTypeIterator = struct { |
| 7177 | 7178 | if (isScalar(zcu, ty)) { |
| 7178 | 7179 | return .byval; |
| 7179 | 7180 | } 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" }; | |
| 7181 | 7209 | return .byref; |
| 7182 | 7210 | } |
| 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; | |
| 7183 | 7230 | }, |
| 7184 | 7231 | .x86_64_sysv, .x86_64_x32 => return try it.next_x86_64_sysv(ty), |
| 7185 | 7232 | .x86_64_win => return it.next_x86_64_win(ty), |
| ... | ... | @@ -7277,7 +7324,7 @@ const ParamTypeIterator = struct { |
| 7277 | 7324 | .x87 => { |
| 7278 | 7325 | it.zig_index += 1; |
| 7279 | 7326 | it.llvm_index += 1; |
| 7280 | it.byval_attr = true; | |
| 7327 | it.byval_attr = .{}; | |
| 7281 | 7328 | return .byref; |
| 7282 | 7329 | }, |
| 7283 | 7330 | .x87up => unreachable, |
| ... | ... | @@ -7285,7 +7332,7 @@ const ParamTypeIterator = struct { |
| 7285 | 7332 | .memory => { |
| 7286 | 7333 | it.zig_index += 1; |
| 7287 | 7334 | it.llvm_index += 1; |
| 7288 | it.byval_attr = true; | |
| 7335 | it.byval_attr = .{}; | |
| 7289 | 7336 | return .byref; |
| 7290 | 7337 | }, |
| 7291 | 7338 | .win_i128 => unreachable, // windows only |
| ... | ... | @@ -7306,7 +7353,7 @@ const ParamTypeIterator = struct { |
| 7306 | 7353 | if (it.llvm_index + classes_len > 6) { |
| 7307 | 7354 | it.zig_index += 1; |
| 7308 | 7355 | it.llvm_index += 1; |
| 7309 | it.byval_attr = true; | |
| 7356 | it.byval_attr = .{}; | |
| 7310 | 7357 | return .byref; |
| 7311 | 7358 | } |
| 7312 | 7359 | } else if (!isByRef(ty, zcu)) { |
| ... | ... | @@ -7340,7 +7387,7 @@ pub fn iterateParamTypes( |
| 7340 | 7387 | .types_len = undefined, |
| 7341 | 7388 | .types_buffer = undefined, |
| 7342 | 7389 | .offsets_buffer = undefined, |
| 7343 | .byval_attr = false, | |
| 7390 | .byval_attr = null, | |
| 7344 | 7391 | }; |
| 7345 | 7392 | } |
| 7346 | 7393 | |
| ... | ... | @@ -7466,7 +7513,39 @@ pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) A |
| 7466 | 7513 | return .by_val; |
| 7467 | 7514 | } else .sret, |
| 7468 | 7515 | .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, | |
| 7470 | 7549 | .x86_64_sysv, .x86_64_x32 => fnReturnStrat_x86_64_sysv(o, ret_ty), |
| 7471 | 7550 | .x86_64_win => fnReturnStrat_x86_64_win(o, ret_ty), |
| 7472 | 7551 | // 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 |
| 4151 | 4151 | .x86_64_regcall_v3_sysv => .LLVM_X86RegCall, |
| 4152 | 4152 | .x86_64_regcall_v4_win => .LLVM_X86RegCall, |
| 4153 | 4153 | .x86_64_vectorcall => .LLVM_vectorcall, |
| 4154 | .x86_sysv => .normal, | |
| 4155 | .x86_win => .normal, | |
| 4154 | .x86_sysv, .x86_win, .x86_mingw => .normal, | |
| 4156 | 4155 | .x86_stdcall => .BORLAND_stdcall, |
| 4157 | 4156 | .x86_fastcall => .BORLAND_msfastcall, |
| 4158 | 4157 | .x86_thiscall => .BORLAND_thiscall, |