authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-09-28 07:23:08-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-10-02 15:59:51-04:00
logd5f09f56e0327685dfcaeb889efd9d6a26461886
tree21b1a26d12efdb7e83890b5c61e873832a07b5ef
parentbc4da9a90743c11c7c0b3e485f46d365d57d87b7

x86_64: fix windows calling convention abi


4 files changed, 5749 insertions(+), 9972 deletions(-)

src/codegen/llvm.zig+3-3
......@@ -12103,7 +12103,7 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: *const st
1210312103 return switch (fn_info.cc) {
1210412104 .auto => returnTypeByRef(zcu, target, return_type),
1210512105 .x86_64_sysv => firstParamSRetSystemV(return_type, zcu, target),
12106 .x86_64_win => x86_64_abi.classifyWindows(return_type, zcu, target) == .memory,
12106 .x86_64_win => x86_64_abi.classifyWindows(return_type, zcu, target, .ret) == .memory,
1210712107 .x86_sysv, .x86_win => isByRef(return_type, zcu),
1210812108 .x86_stdcall => !isScalar(zcu, return_type),
1210912109 .wasm_mvp => wasm_c_abi.classifyType(return_type, zcu) == .indirect,
......@@ -12205,7 +12205,7 @@ fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType)
1220512205fn lowerWin64FnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
1220612206 const zcu = pt.zcu;
1220712207 const return_type = Type.fromInterned(fn_info.return_type);
12208 switch (x86_64_abi.classifyWindows(return_type, zcu, zcu.getTarget())) {
12208 switch (x86_64_abi.classifyWindows(return_type, zcu, zcu.getTarget(), .ret)) {
1220912209 .integer => {
1221012210 if (isScalar(zcu, return_type)) {
1221112211 return o.lowerType(pt, return_type);
......@@ -12476,7 +12476,7 @@ const ParamTypeIterator = struct {
1247612476
1247712477 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
1247812478 const zcu = it.pt.zcu;
12479 switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget())) {
12479 switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) {
1248012480 .integer => {
1248112481 if (isScalar(zcu, ty)) {
1248212482 it.zig_index += 1;
src/codegen/x86_64/CodeGen.zig+5740-9955
......@@ -2292,7 +2292,7 @@ fn genBodyBlock(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22922292}
22932293
22942294fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2295 @setEvalBranchQuota(29_600);
2295 @setEvalBranchQuota(31_000);
22962296 const pt = cg.pt;
22972297 const zcu = pt.zcu;
22982298 const ip = &zcu.intern_pool;
......@@ -4168,6 +4168,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
41684168 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
41694169 } },
41704170 }, .{
4171 .required_cc_abi = .sysv64,
41714172 .required_features = .{ .sse, null, null, null },
41724173 .src_constraints = .{
41734174 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -4201,6 +4202,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42014202 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
42024203 } },
42034204 }, .{
4205 .required_cc_abi = .win64,
4206 .required_features = .{ .sse, null, null, null },
4207 .src_constraints = .{
4208 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
4209 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
4210 .any,
4211 },
4212 .patterns = &.{
4213 .{ .src = .{ .to_mem, .to_mem, .none } },
4214 },
4215 .call_frame = .{ .alignment = .@"16" },
4216 .extra_temps = .{
4217 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4218 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4219 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4220 .unused,
4221 .unused,
4222 .unused,
4223 .unused,
4224 .unused,
4225 .unused,
4226 .unused,
4227 .unused,
4228 },
4229 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
4230 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4231 .each = .{ .once = &.{
4232 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
4233 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
4234 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
4235 } },
4236 }, .{
4237 .required_cc_abi = .sysv64,
42044238 .required_features = .{ .avx, null, null, null },
42054239 .src_constraints = .{
42064240 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -4212,7 +4246,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42124246 },
42134247 .call_frame = .{ .alignment = .@"16" },
42144248 .extra_temps = .{
4215 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4249 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
42164250 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42174251 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42184252 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
......@@ -4227,15 +4261,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42274261 .dst_temps = .{ .mem, .unused },
42284262 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42294263 .each = .{ .once = &.{
4230 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
4231 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
4232 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
4264 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4265 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
4266 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
42334267 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4234 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
4235 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
4236 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4268 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
4269 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4270 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
42374271 } },
42384272 }, .{
4273 .required_cc_abi = .sysv64,
42394274 .required_features = .{ .sse2, null, null, null },
42404275 .src_constraints = .{
42414276 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -4247,7 +4282,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42474282 },
42484283 .call_frame = .{ .alignment = .@"16" },
42494284 .extra_temps = .{
4250 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4285 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
42514286 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42524287 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42534288 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
......@@ -4262,15 +4297,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42624297 .dst_temps = .{ .mem, .unused },
42634298 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42644299 .each = .{ .once = &.{
4265 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
4266 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
4267 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
4300 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4301 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
4302 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
42684303 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4269 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
4270 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
4271 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4304 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
4305 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4306 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
42724307 } },
42734308 }, .{
4309 .required_cc_abi = .sysv64,
42744310 .required_features = .{ .sse, null, null, null },
42754311 .src_constraints = .{
42764312 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -4282,7 +4318,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42824318 },
42834319 .call_frame = .{ .alignment = .@"16" },
42844320 .extra_temps = .{
4285 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
4321 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
42864322 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42874323 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42884324 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
......@@ -4297,13 +4333,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42974333 .dst_temps = .{ .mem, .unused },
42984334 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42994335 .each = .{ .once = &.{
4300 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
4301 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
4302 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
4336 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4337 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
4338 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
43034339 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4304 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
4305 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
4306 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4340 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
4341 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4342 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4343 } },
4344 }, .{
4345 .required_cc_abi = .win64,
4346 .required_features = .{ .avx, null, null, null },
4347 .src_constraints = .{
4348 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4349 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4350 .any,
4351 },
4352 .patterns = &.{
4353 .{ .src = .{ .to_mem, .to_mem, .none } },
4354 },
4355 .call_frame = .{ .alignment = .@"16" },
4356 .extra_temps = .{
4357 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4358 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4359 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4360 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4361 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4362 .unused,
4363 .unused,
4364 .unused,
4365 .unused,
4366 .unused,
4367 .unused,
4368 },
4369 .dst_temps = .{ .mem, .unused },
4370 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4371 .each = .{ .once = &.{
4372 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4373 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
4374 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
4375 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4376 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
4377 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4378 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4379 } },
4380 }, .{
4381 .required_cc_abi = .win64,
4382 .required_features = .{ .sse2, null, null, null },
4383 .src_constraints = .{
4384 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4385 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4386 .any,
4387 },
4388 .patterns = &.{
4389 .{ .src = .{ .to_mem, .to_mem, .none } },
4390 },
4391 .call_frame = .{ .alignment = .@"16" },
4392 .extra_temps = .{
4393 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4394 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4395 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4396 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4397 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4398 .unused,
4399 .unused,
4400 .unused,
4401 .unused,
4402 .unused,
4403 .unused,
4404 },
4405 .dst_temps = .{ .mem, .unused },
4406 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4407 .each = .{ .once = &.{
4408 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4409 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
4410 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
4411 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4412 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
4413 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4414 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4415 } },
4416 }, .{
4417 .required_cc_abi = .win64,
4418 .required_features = .{ .sse, null, null, null },
4419 .src_constraints = .{
4420 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4421 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
4422 .any,
4423 },
4424 .patterns = &.{
4425 .{ .src = .{ .to_mem, .to_mem, .none } },
4426 },
4427 .call_frame = .{ .alignment = .@"16" },
4428 .extra_temps = .{
4429 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4430 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4431 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4432 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4433 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4434 .unused,
4435 .unused,
4436 .unused,
4437 .unused,
4438 .unused,
4439 .unused,
4440 },
4441 .dst_temps = .{ .mem, .unused },
4442 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4443 .each = .{ .once = &.{
4444 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
4445 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
4446 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
4447 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
4448 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
4449 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
4450 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
43074451 } },
43084452 } }) catch |err| switch (err) {
43094453 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -14775,6 +14919,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1477514919 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
1477614920 } },
1477714921 }, .{
14922 .required_cc_abi = .sysv64,
1477814923 .required_features = .{ .sse, null, null, null },
1477914924 .src_constraints = .{
1478014925 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -14808,6 +14953,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1480814953 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
1480914954 } },
1481014955 }, .{
14956 .required_cc_abi = .win64,
14957 .required_features = .{ .sse, null, null, null },
14958 .src_constraints = .{
14959 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
14960 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
14961 .any,
14962 },
14963 .patterns = &.{
14964 .{ .src = .{ .to_mem, .to_mem, .none } },
14965 },
14966 .call_frame = .{ .alignment = .@"16" },
14967 .extra_temps = .{
14968 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
14969 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
14970 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
14971 .unused,
14972 .unused,
14973 .unused,
14974 .unused,
14975 .unused,
14976 .unused,
14977 .unused,
14978 .unused,
14979 },
14980 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
14981 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
14982 .each = .{ .once = &.{
14983 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
14984 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
14985 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
14986 } },
14987 }, .{
14988 .required_cc_abi = .sysv64,
1481114989 .required_features = .{ .avx, null, null, null },
1481214990 .src_constraints = .{
1481314991 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -14819,7 +14997,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1481914997 },
1482014998 .call_frame = .{ .alignment = .@"16" },
1482114999 .extra_temps = .{
14822 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
15000 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
1482315001 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
1482415002 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
1482515003 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
......@@ -14834,15 +15012,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1483415012 .dst_temps = .{ .mem, .unused },
1483515013 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
1483615014 .each = .{ .once = &.{
14837 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
14838 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
14839 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
15015 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15016 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
15017 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
1484015018 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
14841 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
14842 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
14843 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
15019 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
15020 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15021 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
1484415022 } },
1484515023 }, .{
15024 .required_cc_abi = .sysv64,
1484615025 .required_features = .{ .sse2, null, null, null },
1484715026 .src_constraints = .{
1484815027 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -14854,7 +15033,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1485415033 },
1485515034 .call_frame = .{ .alignment = .@"16" },
1485615035 .extra_temps = .{
14857 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
15036 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
1485815037 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
1485915038 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
1486015039 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
......@@ -14869,15 +15048,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1486915048 .dst_temps = .{ .mem, .unused },
1487015049 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
1487115050 .each = .{ .once = &.{
14872 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
14873 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
14874 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
15051 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15052 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
15053 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
1487515054 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
14876 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
14877 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
14878 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
15055 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
15056 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15057 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
1487915058 } },
1488015059 }, .{
15060 .required_cc_abi = .sysv64,
1488115061 .required_features = .{ .sse, null, null, null },
1488215062 .src_constraints = .{
1488315063 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -14889,7 +15069,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1488915069 },
1489015070 .call_frame = .{ .alignment = .@"16" },
1489115071 .extra_temps = .{
14892 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
15072 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
1489315073 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
1489415074 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
1489515075 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
......@@ -14904,13 +15084,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1490415084 .dst_temps = .{ .mem, .unused },
1490515085 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
1490615086 .each = .{ .once = &.{
14907 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
14908 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
14909 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
15087 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15088 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
15089 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
1491015090 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
14911 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
14912 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
14913 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
15091 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
15092 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15093 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
15094 } },
15095 }, .{
15096 .required_cc_abi = .win64,
15097 .required_features = .{ .avx, null, null, null },
15098 .src_constraints = .{
15099 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15100 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15101 .any,
15102 },
15103 .patterns = &.{
15104 .{ .src = .{ .to_mem, .to_mem, .none } },
15105 },
15106 .call_frame = .{ .alignment = .@"16" },
15107 .extra_temps = .{
15108 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
15109 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15110 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
15111 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
15112 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15113 .unused,
15114 .unused,
15115 .unused,
15116 .unused,
15117 .unused,
15118 .unused,
15119 },
15120 .dst_temps = .{ .mem, .unused },
15121 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
15122 .each = .{ .once = &.{
15123 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15124 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
15125 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
15126 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
15127 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
15128 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15129 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
15130 } },
15131 }, .{
15132 .required_cc_abi = .win64,
15133 .required_features = .{ .sse2, null, null, null },
15134 .src_constraints = .{
15135 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15136 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15137 .any,
15138 },
15139 .patterns = &.{
15140 .{ .src = .{ .to_mem, .to_mem, .none } },
15141 },
15142 .call_frame = .{ .alignment = .@"16" },
15143 .extra_temps = .{
15144 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
15145 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15146 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
15147 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
15148 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15149 .unused,
15150 .unused,
15151 .unused,
15152 .unused,
15153 .unused,
15154 .unused,
15155 },
15156 .dst_temps = .{ .mem, .unused },
15157 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
15158 .each = .{ .once = &.{
15159 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15160 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
15161 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
15162 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
15163 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
15164 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15165 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
15166 } },
15167 }, .{
15168 .required_cc_abi = .win64,
15169 .required_features = .{ .sse, null, null, null },
15170 .src_constraints = .{
15171 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15172 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
15173 .any,
15174 },
15175 .patterns = &.{
15176 .{ .src = .{ .to_mem, .to_mem, .none } },
15177 },
15178 .call_frame = .{ .alignment = .@"16" },
15179 .extra_temps = .{
15180 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
15181 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15182 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
15183 .{ .type = .usize, .kind = .{ .extern_func = "__subtf3" } },
15184 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
15185 .unused,
15186 .unused,
15187 .unused,
15188 .unused,
15189 .unused,
15190 .unused,
15191 },
15192 .dst_temps = .{ .mem, .unused },
15193 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
15194 .each = .{ .once = &.{
15195 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
15196 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
15197 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
15198 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
15199 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
15200 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
15201 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
1491415202 } },
1491515203 } }) catch |err| switch (err) {
1491615204 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -24415,6 +24703,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2441524703 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
2441624704 } },
2441724705 }, .{
24706 .required_cc_abi = .sysv64,
2441824707 .required_features = .{ .sse, null, null, null },
2441924708 .src_constraints = .{
2442024709 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -24448,6 +24737,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2444824737 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
2444924738 } },
2445024739 }, .{
24740 .required_cc_abi = .win64,
24741 .required_features = .{ .sse, null, null, null },
24742 .src_constraints = .{
24743 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
24744 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
24745 .any,
24746 },
24747 .patterns = &.{
24748 .{ .src = .{ .to_mem, .to_mem, .none } },
24749 },
24750 .call_frame = .{ .alignment = .@"16" },
24751 .extra_temps = .{
24752 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24753 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
24754 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24755 .unused,
24756 .unused,
24757 .unused,
24758 .unused,
24759 .unused,
24760 .unused,
24761 .unused,
24762 .unused,
24763 },
24764 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
24765 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
24766 .each = .{ .once = &.{
24767 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
24768 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
24769 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
24770 } },
24771 }, .{
24772 .required_cc_abi = .sysv64,
2445124773 .required_features = .{ .avx, null, null, null },
2445224774 .src_constraints = .{
2445324775 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -24459,7 +24781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2445924781 },
2446024782 .call_frame = .{ .alignment = .@"16" },
2446124783 .extra_temps = .{
24462 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24784 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
2446324785 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
2446424786 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
2446524787 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
......@@ -24474,15 +24796,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2447424796 .dst_temps = .{ .mem, .unused },
2447524797 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
2447624798 .each = .{ .once = &.{
24477 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
24478 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
24479 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
24799 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24800 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
24801 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
2448024802 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24481 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
24482 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
24483 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
24803 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
24804 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24805 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
2448424806 } },
2448524807 }, .{
24808 .required_cc_abi = .sysv64,
2448624809 .required_features = .{ .sse2, null, null, null },
2448724810 .src_constraints = .{
2448824811 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -24494,7 +24817,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2449424817 },
2449524818 .call_frame = .{ .alignment = .@"16" },
2449624819 .extra_temps = .{
24497 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24820 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
2449824821 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
2449924822 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
2450024823 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
......@@ -24509,15 +24832,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2450924832 .dst_temps = .{ .mem, .unused },
2451024833 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
2451124834 .each = .{ .once = &.{
24512 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
24513 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
24514 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
24835 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24836 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
24837 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
2451524838 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24516 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
24517 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
24518 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
24839 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
24840 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24841 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
2451924842 } },
2452024843 }, .{
24844 .required_cc_abi = .sysv64,
2452124845 .required_features = .{ .sse, null, null, null },
2452224846 .src_constraints = .{
2452324847 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -24529,7 +24853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2452924853 },
2453024854 .call_frame = .{ .alignment = .@"16" },
2453124855 .extra_temps = .{
24532 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
24856 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
2453324857 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
2453424858 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
2453524859 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
......@@ -24544,13 +24868,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2454424868 .dst_temps = .{ .mem, .unused },
2454524869 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
2454624870 .each = .{ .once = &.{
24547 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
24548 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
24549 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
24871 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24872 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
24873 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
2455024874 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24551 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
24552 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
24553 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
24875 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
24876 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24877 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
24878 } },
24879 }, .{
24880 .required_cc_abi = .win64,
24881 .required_features = .{ .avx, null, null, null },
24882 .src_constraints = .{
24883 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24884 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24885 .any,
24886 },
24887 .patterns = &.{
24888 .{ .src = .{ .to_mem, .to_mem, .none } },
24889 },
24890 .call_frame = .{ .alignment = .@"16" },
24891 .extra_temps = .{
24892 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
24893 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24894 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
24895 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24896 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24897 .unused,
24898 .unused,
24899 .unused,
24900 .unused,
24901 .unused,
24902 .unused,
24903 },
24904 .dst_temps = .{ .mem, .unused },
24905 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
24906 .each = .{ .once = &.{
24907 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24908 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
24909 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
24910 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24911 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
24912 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24913 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
24914 } },
24915 }, .{
24916 .required_cc_abi = .win64,
24917 .required_features = .{ .sse2, null, null, null },
24918 .src_constraints = .{
24919 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24920 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24921 .any,
24922 },
24923 .patterns = &.{
24924 .{ .src = .{ .to_mem, .to_mem, .none } },
24925 },
24926 .call_frame = .{ .alignment = .@"16" },
24927 .extra_temps = .{
24928 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
24929 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24930 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
24931 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24932 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24933 .unused,
24934 .unused,
24935 .unused,
24936 .unused,
24937 .unused,
24938 .unused,
24939 },
24940 .dst_temps = .{ .mem, .unused },
24941 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
24942 .each = .{ .once = &.{
24943 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24944 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
24945 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
24946 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24947 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
24948 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24949 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
24950 } },
24951 }, .{
24952 .required_cc_abi = .win64,
24953 .required_features = .{ .sse, null, null, null },
24954 .src_constraints = .{
24955 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24956 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
24957 .any,
24958 },
24959 .patterns = &.{
24960 .{ .src = .{ .to_mem, .to_mem, .none } },
24961 },
24962 .call_frame = .{ .alignment = .@"16" },
24963 .extra_temps = .{
24964 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
24965 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24966 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
24967 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
24968 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
24969 .unused,
24970 .unused,
24971 .unused,
24972 .unused,
24973 .unused,
24974 .unused,
24975 },
24976 .dst_temps = .{ .mem, .unused },
24977 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
24978 .each = .{ .once = &.{
24979 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
24980 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
24981 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
24982 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
24983 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
24984 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
24985 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
2455424986 } },
2455524987 } }) catch |err| switch (err) {
2455624988 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -26350,18 +26782,53 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2635026782 .{ ._, ._, .add, .tmp0p, .sa(.src0, .add_elem_size), ._, ._ },
2635126783 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
2635226784 } },
26353 }, .{
26354 .required_features = .{ .f16c, null, null, null },
26355 .src_constraints = .{
26356 .{ .scalar_float = .{ .of = .word, .is = .word } },
26357 .{ .scalar_float = .{ .of = .word, .is = .word } },
26358 .any,
26785 } }) catch |err| switch (err) {
26786 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
26787 @tagName(air_tag),
26788 ty.fmt(pt),
26789 ops[0].tracking(cg),
26790 ops[1].tracking(cg),
26791 }),
26792 else => |e| return e,
26793 };
26794 res[0].wrapInt(cg) catch |err| switch (err) {
26795 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
26796 @tagName(air_tag),
26797 cg.typeOf(bin_op.lhs).fmt(pt),
26798 res[0].tracking(cg),
26799 }),
26800 else => |e| return e,
26801 };
26802 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
26803 },
26804 .mul_sat => |air_tag| {
26805 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
26806 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
26807 var res: [1]Temp = undefined;
26808 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
26809 .src_constraints = .{ .{ .exact_signed_int = 8 }, .{ .exact_signed_int = 8 }, .any },
26810 .patterns = &.{
26811 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
26812 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
26813 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
2635926814 },
26815 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26816 .clobbers = .{ .eflags = true },
26817 .each = .{ .once = &.{
26818 .{ ._, .i_, .mul, .src1b, ._, ._, ._ },
26819 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
26820 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
26821 .{ ._, ._, .xor, .dst0b, .sa(.src0, .add_smax), ._, ._ },
26822 } },
26823 }, .{
26824 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
2636026825 .patterns = &.{
26361 .{ .src = .{ .to_sse, .to_sse, .none } },
26826 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
26827 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
26828 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
2636226829 },
2636326830 .extra_temps = .{
26364 .{ .type = .f32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } },
26831 .{ .type = .i8, .kind = .{ .rc = .gphi } },
2636526832 .unused,
2636626833 .unused,
2636726834 .unused,
......@@ -26373,30 +26840,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2637326840 .unused,
2637426841 .unused,
2637526842 },
26376 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26843 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26844 .clobbers = .{ .eflags = true },
2637726845 .each = .{ .once = &.{
26378 .{ ._, .v_ps, .cvtph2, .dst0x, .src0q, ._, ._ },
26379 .{ ._, .v_ps, .cvtph2, .tmp0x, .src1q, ._, ._ },
26380 .{ ._, .v_ss, .mul, .dst0x, .dst0x, .tmp0d, ._ },
26381 .{ ._, .v_, .cvtps2ph, .dst0q, .dst0x, .rm(.{}), ._ },
26846 .{ ._, .i_, .mul, .src1b, ._, ._, ._ },
26847 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
26848 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
26849 .{ ._, ._r, .sa, .tmp0b, .sia(-1, .src0, .add_bit_size), ._, ._ },
26850 .{ ._, ._, .cmp, .tmp0b, .dst0h, ._, ._ },
26851 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
26852 .{ .@"1:", ._r, .sa, .dst0w, .ui(15), ._, ._ },
26853 .{ ._, ._, .xor, .dst0b, .sa(.src0, .add_smax), ._, ._ },
2638226854 } },
2638326855 }, .{
26384 .required_features = .{ .sse, null, null, null },
26385 .src_constraints = .{
26386 .{ .scalar_float = .{ .of = .word, .is = .word } },
26387 .{ .scalar_float = .{ .of = .word, .is = .word } },
26388 .any,
26389 },
26856 .src_constraints = .{ .{ .exact_unsigned_int = 8 }, .{ .exact_unsigned_int = 8 }, .any },
2639026857 .patterns = &.{
26391 .{ .src = .{
26392 .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } },
26393 .{ .to_param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } },
26394 .none,
26395 } },
26858 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
26859 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
26860 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
2639626861 },
26397 .call_frame = .{ .alignment = .@"16" },
2639826862 .extra_temps = .{
26399 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26863 .{ .type = .u8, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2640026864 .unused,
2640126865 .unused,
2640226866 .unused,
......@@ -26409,25 +26873,22 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2640926873 .unused,
2641026874 },
2641126875 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26412 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
26876 .clobbers = .{ .eflags = true },
2641326877 .each = .{ .once = &.{
26414 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
26878 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
26879 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
26880 .{ ._, ._, .@"or", .dst0b, .tmp0b, ._, ._ },
2641526881 } },
2641626882 }, .{
26417 .required_features = .{ .f16c, null, null, null },
26418 .src_constraints = .{
26419 .{ .scalar_float = .{ .of = .qword, .is = .word } },
26420 .{ .scalar_float = .{ .of = .qword, .is = .word } },
26421 .any,
26422 },
26883 .required_features = .{ .cmov, null, null, null },
26884 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
2642326885 .patterns = &.{
26424 .{ .src = .{ .mem, .mem, .none } },
26425 .{ .src = .{ .to_sse, .mem, .none } },
26426 .{ .src = .{ .mem, .to_sse, .none } },
26427 .{ .src = .{ .to_sse, .to_sse, .none } },
26886 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
26887 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
26888 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
2642826889 },
2642926890 .extra_temps = .{
26430 .{ .type = .vector_4_f32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } },
26891 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2643126892 .unused,
2643226893 .unused,
2643326894 .unused,
......@@ -26439,28 +26900,23 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2643926900 .unused,
2644026901 .unused,
2644126902 },
26442 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26903 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26904 .clobbers = .{ .eflags = true },
2644326905 .each = .{ .once = &.{
26444 .{ ._, .v_ps, .cvtph2, .dst0x, .src0q, ._, ._ },
26445 .{ ._, .v_ps, .cvtph2, .tmp0x, .src1q, ._, ._ },
26446 .{ ._, .v_ps, .mul, .dst0x, .dst0x, .tmp0x, ._ },
26447 .{ ._, .v_, .cvtps2ph, .dst0q, .dst0x, .rm(.{}), ._ },
26906 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
26907 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
26908 .{ ._, ._, .cmp, .dst0w, .tmp0w, ._, ._ },
26909 .{ ._, ._a, .cmov, .dst0d, .tmp0d, ._, ._ },
2644826910 } },
2644926911 }, .{
26450 .required_features = .{ .f16c, null, null, null },
26451 .src_constraints = .{
26452 .{ .scalar_float = .{ .of = .xword, .is = .word } },
26453 .{ .scalar_float = .{ .of = .xword, .is = .word } },
26454 .any,
26455 },
26912 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
2645626913 .patterns = &.{
26457 .{ .src = .{ .mem, .mem, .none } },
26458 .{ .src = .{ .to_sse, .mem, .none } },
26459 .{ .src = .{ .mem, .to_sse, .none } },
26460 .{ .src = .{ .to_sse, .to_sse, .none } },
26914 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
26915 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
26916 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
2646126917 },
2646226918 .extra_temps = .{
26463 .{ .type = .vector_8_f32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } },
26919 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2646426920 .unused,
2646526921 .unused,
2646626922 .unused,
......@@ -26472,27 +26928,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2647226928 .unused,
2647326929 .unused,
2647426930 },
26475 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26931 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26932 .clobbers = .{ .eflags = true },
2647626933 .each = .{ .once = &.{
26477 .{ ._, .v_ps, .cvtph2, .dst0y, .src0x, ._, ._ },
26478 .{ ._, .v_ps, .cvtph2, .tmp0y, .src1x, ._, ._ },
26479 .{ ._, .v_ps, .mul, .dst0y, .dst0y, .tmp0y, ._ },
26480 .{ ._, .v_, .cvtps2ph, .dst0x, .dst0y, .rm(.{}), ._ },
26934 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
26935 .{ ._, ._, .cmp, .dst0w, .ua(.src0, .add_umax), ._, ._ },
26936 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
26937 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
2648126938 } },
2648226939 }, .{
26483 .required_features = .{ .f16c, null, null, null },
26484 .src_constraints = .{
26485 .{ .multiple_scalar_float = .{ .of = .xword, .is = .word } },
26486 .{ .multiple_scalar_float = .{ .of = .xword, .is = .word } },
26487 .any,
26488 },
26940 .required_features = .{ .fast_imm16, null, null, null },
26941 .src_constraints = .{ .{ .exact_signed_int = 16 }, .{ .exact_signed_int = 16 }, .any },
2648926942 .patterns = &.{
26490 .{ .src = .{ .to_mem, .to_mem, .none } },
26943 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
26944 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
26945 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2649126946 },
2649226947 .extra_temps = .{
26493 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26494 .{ .type = .vector_8_f32, .kind = .{ .rc = .sse } },
26495 .{ .type = .vector_8_f32, .kind = .{ .rc = .sse } },
26948 .{ .type = .i16, .kind = .{ .reg = .dx } },
26949 .unused,
26950 .unused,
2649626951 .unused,
2649726952 .unused,
2649826953 .unused,
......@@ -26502,33 +26957,28 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2650226957 .unused,
2650326958 .unused,
2650426959 },
26505 .dst_temps = .{ .mem, .unused },
26960 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2650626961 .clobbers = .{ .eflags = true },
2650726962 .each = .{ .once = &.{
26508 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26509 .{ .@"0:", .v_ps, .cvtph2, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
26510 .{ ._, .v_ps, .cvtph2, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
26511 .{ ._, .v_ps, .mul, .tmp1y, .tmp1y, .tmp2y, ._ },
26512 .{ ._, .v_, .cvtps2ph, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1y, .rm(.{}), ._ },
26513 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
26514 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
26963 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
26964 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
26965 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
26966 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
26967 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
26968 .{ ._, ._, .xor, .dst0w, .sa(.src0, .add_smax), ._, ._ },
2651526969 } },
2651626970 }, .{
26517 .required_features = .{ .avx, null, null, null },
26518 .src_constraints = .{
26519 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26520 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26521 .any,
26522 },
26971 .src_constraints = .{ .{ .exact_signed_int = 16 }, .{ .exact_signed_int = 16 }, .any },
2652326972 .patterns = &.{
26524 .{ .src = .{ .to_mem, .to_mem, .none } },
26973 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
26974 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
26975 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2652526976 },
26526 .call_frame = .{ .alignment = .@"16" },
2652726977 .extra_temps = .{
26528 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26529 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
26530 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
26531 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26978 .{ .type = .i16, .kind = .{ .reg = .dx } },
26979 .unused,
26980 .unused,
26981 .unused,
2653226982 .unused,
2653326983 .unused,
2653426984 .unused,
......@@ -26537,34 +26987,29 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2653726987 .unused,
2653826988 .unused,
2653926989 },
26540 .dst_temps = .{ .mem, .unused },
26541 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
26990 .dst_temps = .{ .{ .ref = .src0 }, .unused },
26991 .clobbers = .{ .eflags = true },
2654226992 .each = .{ .once = &.{
26543 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26544 .{ .@"0:", .vp_, .xor, .tmp2x, .tmp2x, .tmp2x, ._ },
26545 .{ ._, .vp_w, .insr, .tmp1x, .tmp2x, .memia(.src0w, .tmp0, .add_unaligned_size), .ui(0) },
26546 .{ ._, .vp_w, .insr, .tmp2x, .tmp2x, .memia(.src1w, .tmp0, .add_unaligned_size), .ui(0) },
26547 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
26548 .{ ._, .vp_w, .extr, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp1x, .ui(0), ._ },
26549 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
26550 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
26993 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
26994 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
26995 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
26996 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
26997 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
26998 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
2655126999 } },
2655227000 }, .{
26553 .required_features = .{ .sse4_1, null, null, null },
26554 .src_constraints = .{
26555 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26556 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26557 .any,
26558 },
27001 .required_features = .{ .fast_imm16, null, null, null },
27002 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
2655927003 .patterns = &.{
26560 .{ .src = .{ .to_mem, .to_mem, .none } },
27004 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27005 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27006 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2656127007 },
26562 .call_frame = .{ .alignment = .@"16" },
2656327008 .extra_temps = .{
26564 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26565 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
26566 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
26567 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
27009 .{ .type = .i16, .kind = .{ .reg = .dx } },
27010 .{ .type = .i16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27011 .unused,
27012 .unused,
2656827013 .unused,
2656927014 .unused,
2657027015 .unused,
......@@ -26573,36 +27018,33 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2657327018 .unused,
2657427019 .unused,
2657527020 },
26576 .dst_temps = .{ .mem, .unused },
26577 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27021 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27022 .clobbers = .{ .eflags = true },
2657827023 .each = .{ .once = &.{
26579 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26580 .{ .@"0:", .p_, .xor, .tmp1x, .tmp1x, ._, ._ },
26581 .{ ._, .p_, .xor, .tmp2x, .tmp2x, ._, ._ },
26582 .{ ._, .p_w, .insr, .tmp1x, .memia(.src0w, .tmp0, .add_unaligned_size), .ui(0), ._ },
26583 .{ ._, .p_w, .insr, .tmp2x, .memia(.src1w, .tmp0, .add_unaligned_size), .ui(0), ._ },
26584 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
26585 .{ ._, .p_w, .extr, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp1x, .ui(0), ._ },
26586 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
26587 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27024 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27025 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27026 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27027 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27028 .{ ._, ._r, .sa, .tmp1w, .sia(-1, .src0, .add_bit_size), ._, ._ },
27029 .{ ._, ._, .cmp, .tmp1w, .tmp0w, ._, ._ },
27030 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27031 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27032 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27033 .{ ._, ._, .xor, .dst0w, .sa(.src0, .add_smax), ._, ._ },
2658827034 } },
2658927035 }, .{
26590 .required_features = .{ .sse2, null, null, null },
26591 .src_constraints = .{
26592 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26593 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26594 .any,
26595 },
27036 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
2659627037 .patterns = &.{
26597 .{ .src = .{ .to_mem, .to_mem, .none } },
27038 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27039 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27040 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2659827041 },
26599 .call_frame = .{ .alignment = .@"16" },
2660027042 .extra_temps = .{
26601 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26602 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
26603 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
26604 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
26605 .{ .type = .f16, .kind = .{ .reg = .ax } },
27043 .{ .type = .i16, .kind = .{ .reg = .dx } },
27044 .{ .type = .i16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27045 .unused,
27046 .unused,
27047 .unused,
2660627048 .unused,
2660727049 .unused,
2660827050 .unused,
......@@ -26610,154 +27052,90 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2661027052 .unused,
2661127053 .unused,
2661227054 },
26613 .dst_temps = .{ .mem, .unused },
26614 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27055 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27056 .clobbers = .{ .eflags = true },
2661527057 .each = .{ .once = &.{
26616 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26617 .{ .@"0:", .p_, .xor, .tmp1x, .tmp1x, ._, ._ },
26618 .{ ._, .p_, .xor, .tmp2x, .tmp2x, ._, ._ },
26619 .{ ._, .p_w, .insr, .tmp1x, .memia(.src0w, .tmp0, .add_unaligned_size), .ui(0), ._ },
26620 .{ ._, .p_w, .insr, .tmp2x, .memia(.src1w, .tmp0, .add_unaligned_size), .ui(0), ._ },
26621 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
26622 .{ ._, .p_w, .extr, .tmp4d, .tmp1x, .ui(0), ._ },
26623 .{ ._, ._, .mov, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp4w, ._, ._ },
26624 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
26625 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27058 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27059 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27060 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27061 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27062 .{ ._, ._r, .sa, .tmp1w, .sia(-1, .src0, .add_bit_size), ._, ._ },
27063 .{ ._, ._, .cmp, .tmp1w, .tmp0w, ._, ._ },
27064 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27065 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27066 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27067 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
2662627068 } },
2662727069 }, .{
26628 .required_features = .{ .sse, null, null, null },
26629 .src_constraints = .{
26630 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26631 .{ .multiple_scalar_float = .{ .of = .word, .is = .word } },
26632 .any,
26633 },
27070 .src_constraints = .{ .{ .exact_unsigned_int = 16 }, .{ .exact_unsigned_int = 16 }, .any },
2663427071 .patterns = &.{
26635 .{ .src = .{ .to_mem, .to_mem, .none } },
27072 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27073 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27074 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2663627075 },
26637 .call_frame = .{ .alignment = .@"16" },
2663827076 .extra_temps = .{
26639 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26640 .{ .type = .f16, .kind = .{ .reg = .ax } },
26641 .{ .type = .f32, .kind = .mem },
26642 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
26643 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
26644 .{ .type = .usize, .kind = .{ .extern_func = "__mulhf3" } },
27077 .{ .type = .u16, .kind = .{ .reg = .dx } },
27078 .unused,
27079 .unused,
27080 .unused,
27081 .unused,
27082 .unused,
2664527083 .unused,
2664627084 .unused,
2664727085 .unused,
2664827086 .unused,
2664927087 .unused,
26650 },
26651 .dst_temps = .{ .mem, .unused },
26652 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
26653 .each = .{ .once = &.{
26654 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26655 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0w, .tmp0, .add_unaligned_size), ._, ._ },
26656 .{ ._, ._, .mov, .mem(.tmp2d), .tmp1d, ._, ._ },
26657 .{ ._, ._ss, .mov, .tmp3x, .mem(.tmp2d), ._, ._ },
26658 .{ ._, ._, .movzx, .tmp1d, .memia(.src1w, .tmp0, .add_unaligned_size), ._, ._ },
26659 .{ ._, ._, .mov, .mem(.tmp2d), .tmp1d, ._, ._ },
26660 .{ ._, ._ss, .mov, .tmp4x, .mem(.tmp2d), ._, ._ },
26661 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
26662 .{ ._, ._ss, .mov, .mem(.tmp2d), .tmp3x, ._, ._ },
26663 .{ ._, ._, .mov, .tmp1d, .mem(.tmp2d), ._, ._ },
26664 .{ ._, ._, .mov, .memia(.dst0w, .tmp0, .add_unaligned_size), .tmp1w, ._, ._ },
26665 .{ ._, ._, .add, .tmp0p, .si(2), ._, ._ },
26666 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
26667 } },
26668 }, .{
26669 .required_features = .{ .avx, null, null, null },
26670 .src_constraints = .{
26671 .{ .scalar_float = .{ .of = .dword, .is = .dword } },
26672 .{ .scalar_float = .{ .of = .dword, .is = .dword } },
26673 .any,
26674 },
26675 .patterns = &.{
26676 .{ .src = .{ .to_sse, .mem, .none } },
26677 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26678 .{ .src = .{ .to_sse, .to_sse, .none } },
26679 },
26680 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26681 .each = .{ .once = &.{
26682 .{ ._, .v_ss, .mul, .dst0x, .src0x, .src1d, ._ },
26683 } },
26684 }, .{
26685 .required_features = .{ .sse, null, null, null },
26686 .src_constraints = .{
26687 .{ .scalar_float = .{ .of = .dword, .is = .dword } },
26688 .{ .scalar_float = .{ .of = .dword, .is = .dword } },
26689 .any,
26690 },
26691 .patterns = &.{
26692 .{ .src = .{ .to_mut_sse, .mem, .none } },
26693 .{ .src = .{ .mem, .to_mut_sse, .none }, .commute = .{ 0, 1 } },
26694 .{ .src = .{ .to_mut_sse, .to_sse, .none } },
2669527088 },
2669627089 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27090 .clobbers = .{ .eflags = true },
2669727091 .each = .{ .once = &.{
26698 .{ ._, ._ss, .mul, .dst0x, .src1d, ._, ._ },
27092 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27093 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27094 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
27095 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
2669927096 } },
2670027097 }, .{
26701 .required_features = .{ .avx, null, null, null },
26702 .src_constraints = .{
26703 .{ .scalar_float = .{ .of = .xword, .is = .dword } },
26704 .{ .scalar_float = .{ .of = .xword, .is = .dword } },
26705 .any,
26706 },
27098 .required_features = .{ .bmi, .cmov, null, null },
27099 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
2670727100 .patterns = &.{
26708 .{ .src = .{ .to_sse, .mem, .none } },
26709 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26710 .{ .src = .{ .to_sse, .to_sse, .none } },
26711 },
26712 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26713 .each = .{ .once = &.{
26714 .{ ._, .v_ps, .mul, .dst0x, .src0x, .src1x, ._ },
26715 } },
26716 }, .{
26717 .required_features = .{ .sse, null, null, null },
26718 .src_constraints = .{
26719 .{ .scalar_float = .{ .of = .xword, .is = .dword } },
26720 .{ .scalar_float = .{ .of = .xword, .is = .dword } },
26721 .any,
27101 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27102 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27103 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2672227104 },
26723 .patterns = &.{
26724 .{ .src = .{ .to_mut_sse, .mem, .none } },
26725 .{ .src = .{ .mem, .to_mut_sse, .none }, .commute = .{ 0, 1 } },
26726 .{ .src = .{ .to_mut_sse, .to_sse, .none } },
27105 .extra_temps = .{
27106 .{ .type = .u16, .kind = .{ .reg = .dx } },
27107 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
27108 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27109 .unused,
27110 .unused,
27111 .unused,
27112 .unused,
27113 .unused,
27114 .unused,
27115 .unused,
27116 .unused,
2672727117 },
2672827118 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27119 .clobbers = .{ .eflags = true },
2672927120 .each = .{ .once = &.{
26730 .{ ._, ._ps, .mul, .dst0x, .src1x, ._, ._ },
26731 } },
26732 }, .{
26733 .required_features = .{ .avx, null, null, null },
26734 .src_constraints = .{
26735 .{ .scalar_float = .{ .of = .yword, .is = .dword } },
26736 .{ .scalar_float = .{ .of = .yword, .is = .dword } },
26737 .any,
26738 },
26739 .patterns = &.{
26740 .{ .src = .{ .to_sse, .mem, .none } },
26741 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26742 .{ .src = .{ .to_sse, .to_sse, .none } },
26743 },
26744 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26745 .each = .{ .once = &.{
26746 .{ ._, .v_ps, .mul, .dst0y, .src0y, .src1y, ._ },
27121 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27122 .{ ._, ._, .mov, .tmp1d, .ua(.src0, .add_umax), ._, ._ },
27123 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27124 .{ ._, ._, .andn, .tmp2d, .tmp1d, .dst0d, ._ },
27125 .{ ._, ._, .@"or", .tmp2w, .tmp0w, ._, ._ },
27126 .{ ._, ._nz, .cmov, .dst0d, .tmp1d, ._, ._ },
2674727127 } },
2674827128 }, .{
26749 .required_features = .{ .avx, null, null, null },
26750 .src_constraints = .{
26751 .{ .multiple_scalar_float = .{ .of = .yword, .is = .dword } },
26752 .{ .multiple_scalar_float = .{ .of = .yword, .is = .dword } },
26753 .any,
26754 },
27129 .required_features = .{ .cmov, .fast_imm16, null, null },
27130 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
2675527131 .patterns = &.{
26756 .{ .src = .{ .to_mem, .to_mem, .none } },
27132 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27133 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27134 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2675727135 },
2675827136 .extra_temps = .{
26759 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26760 .{ .type = .vector_8_f32, .kind = .{ .rc = .sse } },
27137 .{ .type = .u16, .kind = .{ .reg = .dx } },
27138 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2676127139 .unused,
2676227140 .unused,
2676327141 .unused,
......@@ -26768,29 +27146,28 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2676827146 .unused,
2676927147 .unused,
2677027148 },
26771 .dst_temps = .{ .mem, .unused },
27149 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2677227150 .clobbers = .{ .eflags = true },
2677327151 .each = .{ .once = &.{
26774 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26775 .{ .@"0:", .v_ps, .mova, .tmp1y, .memia(.src0y, .tmp0, .add_unaligned_size), ._, ._ },
26776 .{ ._, .v_ps, .mul, .tmp1y, .tmp1y, .memia(.src1y, .tmp0, .add_unaligned_size), ._ },
26777 .{ ._, .v_ps, .mova, .memia(.dst0y, .tmp0, .add_unaligned_size), .tmp1y, ._, ._ },
26778 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
26779 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27152 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27153 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27154 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27155 .{ ._, ._, .@"and", .tmp1w, .sa(.src0, .add_2_smin), ._, ._ },
27156 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27157 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27158 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
2678027159 } },
2678127160 }, .{
26782 .required_features = .{ .sse, null, null, null },
26783 .src_constraints = .{
26784 .{ .multiple_scalar_float = .{ .of = .xword, .is = .dword } },
26785 .{ .multiple_scalar_float = .{ .of = .xword, .is = .dword } },
26786 .any,
26787 },
27161 .required_features = .{ .cmov, null, null, null },
27162 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
2678827163 .patterns = &.{
26789 .{ .src = .{ .to_mem, .to_mem, .none } },
27164 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27165 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27166 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2679027167 },
2679127168 .extra_temps = .{
26792 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26793 .{ .type = .vector_4_f32, .kind = .{ .rc = .sse } },
27169 .{ .type = .u16, .kind = .{ .reg = .dx } },
27170 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2679427171 .unused,
2679527172 .unused,
2679627173 .unused,
......@@ -26801,61 +27178,28 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2680127178 .unused,
2680227179 .unused,
2680327180 },
26804 .dst_temps = .{ .mem, .unused },
26805 .clobbers = .{ .eflags = true },
26806 .each = .{ .once = &.{
26807 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26808 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
26809 .{ ._, ._ps, .mul, .tmp1x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
26810 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
26811 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
26812 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
26813 } },
26814 }, .{
26815 .required_features = .{ .avx, null, null, null },
26816 .src_constraints = .{
26817 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26818 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26819 .any,
26820 },
26821 .patterns = &.{
26822 .{ .src = .{ .to_sse, .mem, .none } },
26823 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26824 .{ .src = .{ .to_sse, .to_sse, .none } },
26825 },
26826 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26827 .each = .{ .once = &.{
26828 .{ ._, .v_sd, .mul, .dst0x, .src0x, .src1q, ._ },
26829 } },
26830 }, .{
26831 .required_features = .{ .sse2, null, null, null },
26832 .src_constraints = .{
26833 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26834 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26835 .any,
26836 },
26837 .patterns = &.{
26838 .{ .src = .{ .to_mut_sse, .mem, .none } },
26839 .{ .src = .{ .mem, .to_mut_sse, .none }, .commute = .{ 0, 1 } },
26840 .{ .src = .{ .to_mut_sse, .to_sse, .none } },
26841 },
2684227181 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27182 .clobbers = .{ .eflags = true },
2684327183 .each = .{ .once = &.{
26844 .{ ._, ._sd, .mul, .dst0x, .src1q, ._, ._ },
27184 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27185 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27186 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27187 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27188 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27189 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27190 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
2684527191 } },
2684627192 }, .{
26847 .required_features = .{ .x87, null, null, null },
26848 .src_constraints = .{
26849 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26850 .{ .scalar_float = .{ .of = .qword, .is = .qword } },
26851 .any,
26852 },
27193 .required_features = .{ .fast_imm16, null, null, null },
27194 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
2685327195 .patterns = &.{
26854 .{ .src = .{ .mem, .mem, .none } },
27196 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27197 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27198 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2685527199 },
2685627200 .extra_temps = .{
26857 .{ .type = .f64, .kind = .{ .reg = .st6 } },
26858 .{ .type = .f64, .kind = .{ .reg = .st7 } },
27201 .{ .type = .u16, .kind = .{ .reg = .dx } },
27202 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2685927203 .unused,
2686027204 .unused,
2686127205 .unused,
......@@ -26866,73 +27210,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2686627210 .unused,
2686727211 .unused,
2686827212 },
26869 .dst_temps = .{ .mem, .unused },
26870 .each = .{ .once = &.{
26871 .{ ._, .f_, .ld, .src0q, ._, ._, ._ },
26872 .{ ._, .f_, .mul, .src1q, ._, ._, ._ },
26873 .{ ._, .f_p, .st, .dst0q, ._, ._, ._ },
26874 } },
26875 }, .{
26876 .required_features = .{ .avx, null, null, null },
26877 .src_constraints = .{
26878 .{ .scalar_float = .{ .of = .xword, .is = .qword } },
26879 .{ .scalar_float = .{ .of = .xword, .is = .qword } },
26880 .any,
26881 },
26882 .patterns = &.{
26883 .{ .src = .{ .to_sse, .mem, .none } },
26884 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26885 .{ .src = .{ .to_sse, .to_sse, .none } },
26886 },
26887 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26888 .each = .{ .once = &.{
26889 .{ ._, .v_pd, .mul, .dst0x, .src0x, .src1x, ._ },
26890 } },
26891 }, .{
26892 .required_features = .{ .sse2, null, null, null },
26893 .src_constraints = .{
26894 .{ .scalar_float = .{ .of = .xword, .is = .qword } },
26895 .{ .scalar_float = .{ .of = .xword, .is = .qword } },
26896 .any,
26897 },
26898 .patterns = &.{
26899 .{ .src = .{ .to_mut_sse, .mem, .none } },
26900 .{ .src = .{ .mem, .to_mut_sse, .none }, .commute = .{ 0, 1 } },
26901 .{ .src = .{ .to_mut_sse, .to_sse, .none } },
26902 },
2690327213 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27214 .clobbers = .{ .eflags = true },
2690427215 .each = .{ .once = &.{
26905 .{ ._, ._pd, .mul, .dst0x, .src1x, ._, ._ },
26906 } },
26907 }, .{
26908 .required_features = .{ .avx, null, null, null },
26909 .src_constraints = .{
26910 .{ .scalar_float = .{ .of = .yword, .is = .qword } },
26911 .{ .scalar_float = .{ .of = .yword, .is = .qword } },
26912 .any,
26913 },
26914 .patterns = &.{
26915 .{ .src = .{ .to_sse, .mem, .none } },
26916 .{ .src = .{ .mem, .to_sse, .none }, .commute = .{ 0, 1 } },
26917 .{ .src = .{ .to_sse, .to_sse, .none } },
26918 },
26919 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
26920 .each = .{ .once = &.{
26921 .{ ._, .v_pd, .mul, .dst0y, .src0y, .src1y, ._ },
27216 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27217 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27218 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27219 .{ ._, ._, .@"and", .tmp1w, .sa(.src0, .add_2_smin), ._, ._ },
27220 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27221 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27222 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
2692227223 } },
2692327224 }, .{
26924 .required_features = .{ .avx, null, null, null },
26925 .src_constraints = .{
26926 .{ .multiple_scalar_float = .{ .of = .yword, .is = .qword } },
26927 .{ .multiple_scalar_float = .{ .of = .yword, .is = .qword } },
26928 .any,
26929 },
27225 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
2693027226 .patterns = &.{
26931 .{ .src = .{ .to_mem, .to_mem, .none } },
27227 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27228 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27229 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
2693227230 },
2693327231 .extra_temps = .{
26934 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26935 .{ .type = .vector_4_f64, .kind = .{ .rc = .sse } },
27232 .{ .type = .u16, .kind = .{ .reg = .dx } },
27233 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2693627234 .unused,
2693727235 .unused,
2693827236 .unused,
......@@ -26943,29 +27241,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2694327241 .unused,
2694427242 .unused,
2694527243 },
26946 .dst_temps = .{ .mem, .unused },
27244 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2694727245 .clobbers = .{ .eflags = true },
2694827246 .each = .{ .once = &.{
26949 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26950 .{ .@"0:", .v_pd, .mova, .tmp1y, .memia(.src0y, .tmp0, .add_unaligned_size), ._, ._ },
26951 .{ ._, .v_pd, .mul, .tmp1y, .tmp1y, .memia(.src1y, .tmp0, .add_unaligned_size), ._ },
26952 .{ ._, .v_pd, .mova, .memia(.dst0y, .tmp0, .add_unaligned_size), .tmp1y, ._, ._ },
26953 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
26954 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27247 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27248 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27249 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27250 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27251 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27252 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27253 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
2695527254 } },
2695627255 }, .{
26957 .required_features = .{ .sse2, null, null, null },
26958 .src_constraints = .{
26959 .{ .multiple_scalar_float = .{ .of = .xword, .is = .qword } },
26960 .{ .multiple_scalar_float = .{ .of = .xword, .is = .qword } },
26961 .any,
26962 },
27256 .src_constraints = .{ .{ .exact_signed_int = 32 }, .{ .exact_signed_int = 32 }, .any },
2696327257 .patterns = &.{
26964 .{ .src = .{ .to_mem, .to_mem, .none } },
27258 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27259 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27260 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2696527261 },
2696627262 .extra_temps = .{
26967 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
26968 .{ .type = .vector_2_f64, .kind = .{ .rc = .sse } },
27263 .{ .type = .i32, .kind = .{ .reg = .edx } },
27264 .unused,
2696927265 .unused,
2697027266 .unused,
2697127267 .unused,
......@@ -26976,30 +27272,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2697627272 .unused,
2697727273 .unused,
2697827274 },
26979 .dst_temps = .{ .mem, .unused },
27275 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2698027276 .clobbers = .{ .eflags = true },
2698127277 .each = .{ .once = &.{
26982 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
26983 .{ .@"0:", ._pd, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
26984 .{ ._, ._pd, .mul, .tmp1x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
26985 .{ ._, ._pd, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
26986 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
26987 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27278 .{ ._, .i_, .mul, .src1d, ._, ._, ._ },
27279 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
27280 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
27281 .{ ._, ._r, .sa, .dst0d, .ui(31), ._, ._ },
27282 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
2698827283 } },
2698927284 }, .{
26990 .required_features = .{ .x87, null, null, null },
26991 .src_constraints = .{
26992 .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } },
26993 .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } },
26994 .any,
26995 },
27285 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
2699627286 .patterns = &.{
26997 .{ .src = .{ .to_mem, .to_mem, .none } },
27287 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27288 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27289 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2699827290 },
2699927291 .extra_temps = .{
27000 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27001 .{ .type = .f64, .kind = .{ .reg = .st6 } },
27002 .{ .type = .f64, .kind = .{ .reg = .st7 } },
27292 .{ .type = .i32, .kind = .{ .reg = .edx } },
27293 .{ .type = .i32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27294 .unused,
2700327295 .unused,
2700427296 .unused,
2700527297 .unused,
......@@ -27009,29 +27301,29 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2700927301 .unused,
2701027302 .unused,
2701127303 },
27012 .dst_temps = .{ .mem, .unused },
27304 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2701327305 .clobbers = .{ .eflags = true },
2701427306 .each = .{ .once = &.{
27015 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
27016 .{ .@"0:", .f_, .ld, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._, ._ },
27017 .{ ._, .f_, .mul, .memia(.src1q, .tmp0, .add_unaligned_size), ._, ._, ._ },
27018 .{ ._, .f_p, .st, .memia(.dst0q, .tmp0, .add_unaligned_size), ._, ._, ._ },
27019 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },
27020 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27307 .{ ._, .i_, .mul, .src1d, ._, ._, ._ },
27308 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27309 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27310 .{ ._, ._r, .sa, .tmp1d, .sia(-1, .src0, .add_bit_size), ._, ._ },
27311 .{ ._, ._, .cmp, .tmp1d, .tmp0d, ._, ._ },
27312 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27313 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27314 .{ ._, ._r, .sa, .dst0d, .ui(31), ._, ._ },
27315 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
2702127316 } },
2702227317 }, .{
27023 .required_features = .{ .x87, null, null, null },
27024 .src_constraints = .{
27025 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
27026 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
27027 .any,
27028 },
27318 .src_constraints = .{ .{ .exact_unsigned_int = 32 }, .{ .exact_unsigned_int = 32 }, .any },
2702927319 .patterns = &.{
27030 .{ .src = .{ .mem, .mem, .none } },
27320 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27321 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27322 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2703127323 },
2703227324 .extra_temps = .{
27033 .{ .type = .f80, .kind = .{ .reg = .st6 } },
27034 .{ .type = .f80, .kind = .{ .reg = .st7 } },
27325 .{ .type = .u32, .kind = .{ .reg = .edx } },
27326 .unused,
2703527327 .unused,
2703627328 .unused,
2703727329 .unused,
......@@ -27042,29 +27334,25 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2704227334 .unused,
2704327335 .unused,
2704427336 },
27045 .dst_temps = .{ .{ .rc = .x87 }, .unused },
27337 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27338 .clobbers = .{ .eflags = true },
2704627339 .each = .{ .once = &.{
27047 .{ ._, .f_, .ld, .src0t, ._, ._, ._ },
27048 .{ ._, .f_, .ld, .src1t, ._, ._, ._ },
27049 .{ ._, .f_p, .mul, ._, ._, ._, ._ },
27050 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
27340 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27341 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
27342 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
2705127343 } },
2705227344 }, .{
27053 .required_features = .{ .x87, null, null, null },
27054 .src_constraints = .{
27055 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
27056 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
27057 .any,
27058 },
27345 .required_features = .{ .bmi, .cmov, null, null },
27346 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
2705927347 .patterns = &.{
27060 .{ .src = .{ .to_x87, .mem, .none }, .commute = .{ 0, 1 } },
27061 .{ .src = .{ .mem, .to_x87, .none } },
27062 .{ .src = .{ .to_x87, .to_x87, .none } },
27348 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27349 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27350 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2706327351 },
2706427352 .extra_temps = .{
27065 .{ .type = .f80, .kind = .{ .reg = .st7 } },
27066 .unused,
27067 .unused,
27353 .{ .type = .u32, .kind = .{ .reg = .edx } },
27354 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
27355 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2706827356 .unused,
2706927357 .unused,
2707027358 .unused,
......@@ -27074,26 +27362,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2707427362 .unused,
2707527363 .unused,
2707627364 },
27077 .dst_temps = .{ .{ .rc = .x87 }, .unused },
27365 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27366 .clobbers = .{ .eflags = true },
2707827367 .each = .{ .once = &.{
27079 .{ ._, .f_, .ld, .src0t, ._, ._, ._ },
27080 .{ ._, .f_, .mul, .tmp0t, .src1t, ._, ._ },
27081 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
27368 .{ ._, ._, .mov, .tmp1d, .ua(.src0, .add_umax), ._, ._ },
27369 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27370 .{ ._, ._, .andn, .tmp2d, .tmp1d, .dst0d, ._ },
27371 .{ ._, ._, .@"or", .tmp2d, .tmp0d, ._, ._ },
27372 .{ ._, ._nz, .cmov, .dst0d, .tmp1d, ._, ._ },
2708227373 } },
2708327374 }, .{
27084 .required_features = .{ .x87, null, null, null },
27085 .src_constraints = .{
27086 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
27087 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
27088 .any,
27089 },
27375 .required_features = .{ .cmov, null, null, null },
27376 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
2709027377 .patterns = &.{
27091 .{ .src = .{ .to_mem, .to_mem, .none } },
27378 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27379 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27380 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2709227381 },
2709327382 .extra_temps = .{
27094 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27095 .{ .type = .f80, .kind = .{ .reg = .st6 } },
27096 .{ .type = .f80, .kind = .{ .reg = .st7 } },
27383 .{ .type = .u32, .kind = .{ .reg = .edx } },
27384 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27385 .unused,
2709727386 .unused,
2709827387 .unused,
2709927388 .unused,
......@@ -27103,35 +27392,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2710327392 .unused,
2710427393 .unused,
2710527394 },
27106 .dst_temps = .{ .mem, .unused },
27395 .dst_temps = .{ .{ .ref = .src0 }, .unused },
2710727396 .clobbers = .{ .eflags = true },
2710827397 .each = .{ .once = &.{
27109 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
27110 .{ .@"0:", .f_, .ld, .memia(.src0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
27111 .{ ._, .f_, .ld, .memia(.src1t, .tmp0, .add_unaligned_size), ._, ._, ._ },
27112 .{ ._, .f_p, .mul, ._, ._, ._, ._ },
27113 .{ ._, .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
27114 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
27115 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27398 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27399 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27400 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27401 .{ ._, ._, .@"or", .tmp1d, .tmp0d, ._, ._ },
27402 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27403 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
2711627404 } },
2711727405 }, .{
27118 .required_features = .{ .sse, null, null, null },
27119 .src_constraints = .{
27120 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
27121 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
27122 .any,
27123 },
27406 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
2712427407 .patterns = &.{
27125 .{ .src = .{
27126 .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } },
27127 .{ .to_param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } },
27128 .none,
27129 } },
27408 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27409 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27410 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
2713027411 },
27131 .call_frame = .{ .alignment = .@"16" },
2713227412 .extra_temps = .{
27133 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27134 .unused,
27413 .{ .type = .u32, .kind = .{ .reg = .edx } },
27414 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
2713527415 .unused,
2713627416 .unused,
2713727417 .unused,
......@@ -27143,775 +27423,25 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2714327423 .unused,
2714427424 },
2714527425 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27146 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27426 .clobbers = .{ .eflags = true },
2714727427 .each = .{ .once = &.{
27148 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
27428 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27429 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27430 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27431 .{ ._, ._, .@"or", .tmp1d, .tmp0d, ._, ._ },
27432 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27433 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
2714927434 } },
2715027435 }, .{
27151 .required_features = .{ .avx, null, null, null },
27152 .src_constraints = .{
27153 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27154 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27155 .any,
27156 },
27436 .required_features = .{ .@"64bit", null, null, null },
27437 .src_constraints = .{ .{ .exact_signed_int = 64 }, .{ .exact_signed_int = 64 }, .any },
2715727438 .patterns = &.{
27158 .{ .src = .{ .to_mem, .to_mem, .none } },
27439 .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
27440 .{ .src = .{ .mem, .{ .to_reg = .rax }, .none }, .commute = .{ 0, 1 } },
27441 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
2715927442 },
27160 .call_frame = .{ .alignment = .@"16" },
2716127443 .extra_temps = .{
27162 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27163 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
27164 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
27165 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27166 .unused,
27167 .unused,
27168 .unused,
27169 .unused,
27170 .unused,
27171 .unused,
27172 .unused,
27173 },
27174 .dst_temps = .{ .mem, .unused },
27175 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27176 .each = .{ .once = &.{
27177 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
27178 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
27179 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
27180 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
27181 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
27182 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
27183 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27184 } },
27185 }, .{
27186 .required_features = .{ .sse2, null, null, null },
27187 .src_constraints = .{
27188 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27189 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27190 .any,
27191 },
27192 .patterns = &.{
27193 .{ .src = .{ .to_mem, .to_mem, .none } },
27194 },
27195 .call_frame = .{ .alignment = .@"16" },
27196 .extra_temps = .{
27197 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27198 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
27199 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
27200 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27201 .unused,
27202 .unused,
27203 .unused,
27204 .unused,
27205 .unused,
27206 .unused,
27207 .unused,
27208 },
27209 .dst_temps = .{ .mem, .unused },
27210 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27211 .each = .{ .once = &.{
27212 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
27213 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
27214 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
27215 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
27216 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
27217 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
27218 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27219 } },
27220 }, .{
27221 .required_features = .{ .sse, null, null, null },
27222 .src_constraints = .{
27223 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27224 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
27225 .any,
27226 },
27227 .patterns = &.{
27228 .{ .src = .{ .to_mem, .to_mem, .none } },
27229 },
27230 .call_frame = .{ .alignment = .@"16" },
27231 .extra_temps = .{
27232 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
27233 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
27234 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
27235 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
27236 .unused,
27237 .unused,
27238 .unused,
27239 .unused,
27240 .unused,
27241 .unused,
27242 .unused,
27243 },
27244 .dst_temps = .{ .mem, .unused },
27245 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
27246 .each = .{ .once = &.{
27247 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
27248 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
27249 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
27250 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
27251 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
27252 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
27253 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
27254 } },
27255 } }) catch |err| switch (err) {
27256 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
27257 @tagName(air_tag),
27258 ty.fmt(pt),
27259 ops[0].tracking(cg),
27260 ops[1].tracking(cg),
27261 }),
27262 else => |e| return e,
27263 };
27264 res[0].wrapInt(cg) catch |err| switch (err) {
27265 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
27266 @tagName(air_tag),
27267 cg.typeOf(bin_op.lhs).fmt(pt),
27268 res[0].tracking(cg),
27269 }),
27270 else => |e| return e,
27271 };
27272 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
27273 },
27274 .mul_sat => |air_tag| {
27275 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
27276 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
27277 var res: [1]Temp = undefined;
27278 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
27279 .src_constraints = .{ .{ .exact_signed_int = 8 }, .{ .exact_signed_int = 8 }, .any },
27280 .patterns = &.{
27281 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
27282 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
27283 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
27284 },
27285 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27286 .clobbers = .{ .eflags = true },
27287 .each = .{ .once = &.{
27288 .{ ._, .i_, .mul, .src1b, ._, ._, ._ },
27289 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
27290 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27291 .{ ._, ._, .xor, .dst0b, .sa(.src0, .add_smax), ._, ._ },
27292 } },
27293 }, .{
27294 .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
27295 .patterns = &.{
27296 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
27297 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
27298 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
27299 },
27300 .extra_temps = .{
27301 .{ .type = .i8, .kind = .{ .rc = .gphi } },
27302 .unused,
27303 .unused,
27304 .unused,
27305 .unused,
27306 .unused,
27307 .unused,
27308 .unused,
27309 .unused,
27310 .unused,
27311 .unused,
27312 },
27313 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27314 .clobbers = .{ .eflags = true },
27315 .each = .{ .once = &.{
27316 .{ ._, .i_, .mul, .src1b, ._, ._, ._ },
27317 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27318 .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
27319 .{ ._, ._r, .sa, .tmp0b, .sia(-1, .src0, .add_bit_size), ._, ._ },
27320 .{ ._, ._, .cmp, .tmp0b, .dst0h, ._, ._ },
27321 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27322 .{ .@"1:", ._r, .sa, .dst0w, .ui(15), ._, ._ },
27323 .{ ._, ._, .xor, .dst0b, .sa(.src0, .add_smax), ._, ._ },
27324 } },
27325 }, .{
27326 .src_constraints = .{ .{ .exact_unsigned_int = 8 }, .{ .exact_unsigned_int = 8 }, .any },
27327 .patterns = &.{
27328 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
27329 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
27330 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
27331 },
27332 .extra_temps = .{
27333 .{ .type = .u8, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27334 .unused,
27335 .unused,
27336 .unused,
27337 .unused,
27338 .unused,
27339 .unused,
27340 .unused,
27341 .unused,
27342 .unused,
27343 .unused,
27344 },
27345 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27346 .clobbers = .{ .eflags = true },
27347 .each = .{ .once = &.{
27348 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
27349 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
27350 .{ ._, ._, .@"or", .dst0b, .tmp0b, ._, ._ },
27351 } },
27352 }, .{
27353 .required_features = .{ .cmov, null, null, null },
27354 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
27355 .patterns = &.{
27356 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
27357 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
27358 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
27359 },
27360 .extra_temps = .{
27361 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27362 .unused,
27363 .unused,
27364 .unused,
27365 .unused,
27366 .unused,
27367 .unused,
27368 .unused,
27369 .unused,
27370 .unused,
27371 .unused,
27372 },
27373 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27374 .clobbers = .{ .eflags = true },
27375 .each = .{ .once = &.{
27376 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
27377 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27378 .{ ._, ._, .cmp, .dst0w, .tmp0w, ._, ._ },
27379 .{ ._, ._a, .cmov, .dst0d, .tmp0d, ._, ._ },
27380 } },
27381 }, .{
27382 .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
27383 .patterns = &.{
27384 .{ .src = .{ .{ .to_reg = .al }, .mem, .none } },
27385 .{ .src = .{ .mem, .{ .to_reg = .al }, .none }, .commute = .{ 0, 1 } },
27386 .{ .src = .{ .{ .to_reg = .al }, .to_gpr, .none } },
27387 },
27388 .extra_temps = .{
27389 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27390 .unused,
27391 .unused,
27392 .unused,
27393 .unused,
27394 .unused,
27395 .unused,
27396 .unused,
27397 .unused,
27398 .unused,
27399 .unused,
27400 },
27401 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27402 .clobbers = .{ .eflags = true },
27403 .each = .{ .once = &.{
27404 .{ ._, ._, .mul, .src1b, ._, ._, ._ },
27405 .{ ._, ._, .cmp, .dst0w, .ua(.src0, .add_umax), ._, ._ },
27406 .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
27407 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
27408 } },
27409 }, .{
27410 .required_features = .{ .fast_imm16, null, null, null },
27411 .src_constraints = .{ .{ .exact_signed_int = 16 }, .{ .exact_signed_int = 16 }, .any },
27412 .patterns = &.{
27413 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27414 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27415 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27416 },
27417 .extra_temps = .{
27418 .{ .type = .i16, .kind = .{ .reg = .dx } },
27419 .unused,
27420 .unused,
27421 .unused,
27422 .unused,
27423 .unused,
27424 .unused,
27425 .unused,
27426 .unused,
27427 .unused,
27428 .unused,
27429 },
27430 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27431 .clobbers = .{ .eflags = true },
27432 .each = .{ .once = &.{
27433 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27434 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27435 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
27436 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
27437 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27438 .{ ._, ._, .xor, .dst0w, .sa(.src0, .add_smax), ._, ._ },
27439 } },
27440 }, .{
27441 .src_constraints = .{ .{ .exact_signed_int = 16 }, .{ .exact_signed_int = 16 }, .any },
27442 .patterns = &.{
27443 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27444 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27445 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27446 },
27447 .extra_temps = .{
27448 .{ .type = .i16, .kind = .{ .reg = .dx } },
27449 .unused,
27450 .unused,
27451 .unused,
27452 .unused,
27453 .unused,
27454 .unused,
27455 .unused,
27456 .unused,
27457 .unused,
27458 .unused,
27459 },
27460 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27461 .clobbers = .{ .eflags = true },
27462 .each = .{ .once = &.{
27463 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27464 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27465 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
27466 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
27467 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27468 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
27469 } },
27470 }, .{
27471 .required_features = .{ .fast_imm16, null, null, null },
27472 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
27473 .patterns = &.{
27474 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27475 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27476 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27477 },
27478 .extra_temps = .{
27479 .{ .type = .i16, .kind = .{ .reg = .dx } },
27480 .{ .type = .i16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27481 .unused,
27482 .unused,
27483 .unused,
27484 .unused,
27485 .unused,
27486 .unused,
27487 .unused,
27488 .unused,
27489 .unused,
27490 },
27491 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27492 .clobbers = .{ .eflags = true },
27493 .each = .{ .once = &.{
27494 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27495 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27496 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27497 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27498 .{ ._, ._r, .sa, .tmp1w, .sia(-1, .src0, .add_bit_size), ._, ._ },
27499 .{ ._, ._, .cmp, .tmp1w, .tmp0w, ._, ._ },
27500 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27501 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27502 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27503 .{ ._, ._, .xor, .dst0w, .sa(.src0, .add_smax), ._, ._ },
27504 } },
27505 }, .{
27506 .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
27507 .patterns = &.{
27508 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27509 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27510 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27511 },
27512 .extra_temps = .{
27513 .{ .type = .i16, .kind = .{ .reg = .dx } },
27514 .{ .type = .i16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27515 .unused,
27516 .unused,
27517 .unused,
27518 .unused,
27519 .unused,
27520 .unused,
27521 .unused,
27522 .unused,
27523 .unused,
27524 },
27525 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27526 .clobbers = .{ .eflags = true },
27527 .each = .{ .once = &.{
27528 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27529 .{ ._, .i_, .mul, .src1w, ._, ._, ._ },
27530 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27531 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27532 .{ ._, ._r, .sa, .tmp1w, .sia(-1, .src0, .add_bit_size), ._, ._ },
27533 .{ ._, ._, .cmp, .tmp1w, .tmp0w, ._, ._ },
27534 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27535 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27536 .{ ._, ._r, .sa, .dst0w, .ui(15), ._, ._ },
27537 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
27538 } },
27539 }, .{
27540 .src_constraints = .{ .{ .exact_unsigned_int = 16 }, .{ .exact_unsigned_int = 16 }, .any },
27541 .patterns = &.{
27542 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27543 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27544 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27545 },
27546 .extra_temps = .{
27547 .{ .type = .u16, .kind = .{ .reg = .dx } },
27548 .unused,
27549 .unused,
27550 .unused,
27551 .unused,
27552 .unused,
27553 .unused,
27554 .unused,
27555 .unused,
27556 .unused,
27557 .unused,
27558 },
27559 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27560 .clobbers = .{ .eflags = true },
27561 .each = .{ .once = &.{
27562 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27563 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27564 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
27565 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
27566 } },
27567 }, .{
27568 .required_features = .{ .bmi, .cmov, null, null },
27569 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
27570 .patterns = &.{
27571 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27572 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27573 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27574 },
27575 .extra_temps = .{
27576 .{ .type = .u16, .kind = .{ .reg = .dx } },
27577 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
27578 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27579 .unused,
27580 .unused,
27581 .unused,
27582 .unused,
27583 .unused,
27584 .unused,
27585 .unused,
27586 .unused,
27587 },
27588 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27589 .clobbers = .{ .eflags = true },
27590 .each = .{ .once = &.{
27591 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27592 .{ ._, ._, .mov, .tmp1d, .ua(.src0, .add_umax), ._, ._ },
27593 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27594 .{ ._, ._, .andn, .tmp2d, .tmp1d, .dst0d, ._ },
27595 .{ ._, ._, .@"or", .tmp2w, .tmp0w, ._, ._ },
27596 .{ ._, ._nz, .cmov, .dst0d, .tmp1d, ._, ._ },
27597 } },
27598 }, .{
27599 .required_features = .{ .cmov, .fast_imm16, null, null },
27600 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
27601 .patterns = &.{
27602 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27603 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27604 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27605 },
27606 .extra_temps = .{
27607 .{ .type = .u16, .kind = .{ .reg = .dx } },
27608 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27609 .unused,
27610 .unused,
27611 .unused,
27612 .unused,
27613 .unused,
27614 .unused,
27615 .unused,
27616 .unused,
27617 .unused,
27618 },
27619 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27620 .clobbers = .{ .eflags = true },
27621 .each = .{ .once = &.{
27622 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27623 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27624 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27625 .{ ._, ._, .@"and", .tmp1w, .sa(.src0, .add_2_smin), ._, ._ },
27626 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27627 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27628 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
27629 } },
27630 }, .{
27631 .required_features = .{ .cmov, null, null, null },
27632 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
27633 .patterns = &.{
27634 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27635 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27636 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27637 },
27638 .extra_temps = .{
27639 .{ .type = .u16, .kind = .{ .reg = .dx } },
27640 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27641 .unused,
27642 .unused,
27643 .unused,
27644 .unused,
27645 .unused,
27646 .unused,
27647 .unused,
27648 .unused,
27649 .unused,
27650 },
27651 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27652 .clobbers = .{ .eflags = true },
27653 .each = .{ .once = &.{
27654 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27655 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27656 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27657 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27658 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27659 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27660 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
27661 } },
27662 }, .{
27663 .required_features = .{ .fast_imm16, null, null, null },
27664 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
27665 .patterns = &.{
27666 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27667 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27668 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27669 },
27670 .extra_temps = .{
27671 .{ .type = .u16, .kind = .{ .reg = .dx } },
27672 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27673 .unused,
27674 .unused,
27675 .unused,
27676 .unused,
27677 .unused,
27678 .unused,
27679 .unused,
27680 .unused,
27681 .unused,
27682 },
27683 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27684 .clobbers = .{ .eflags = true },
27685 .each = .{ .once = &.{
27686 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27687 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27688 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27689 .{ ._, ._, .@"and", .tmp1w, .sa(.src0, .add_2_smin), ._, ._ },
27690 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27691 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27692 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
27693 } },
27694 }, .{
27695 .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
27696 .patterns = &.{
27697 .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
27698 .{ .src = .{ .mem, .{ .to_reg = .ax }, .none }, .commute = .{ 0, 1 } },
27699 .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
27700 },
27701 .extra_temps = .{
27702 .{ .type = .u16, .kind = .{ .reg = .dx } },
27703 .{ .type = .u16, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27704 .unused,
27705 .unused,
27706 .unused,
27707 .unused,
27708 .unused,
27709 .unused,
27710 .unused,
27711 .unused,
27712 .unused,
27713 },
27714 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27715 .clobbers = .{ .eflags = true },
27716 .each = .{ .once = &.{
27717 .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ },
27718 .{ ._, ._, .mul, .src1w, ._, ._, ._ },
27719 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27720 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27721 .{ ._, ._, .@"or", .tmp1w, .tmp0w, ._, ._ },
27722 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27723 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
27724 } },
27725 }, .{
27726 .src_constraints = .{ .{ .exact_signed_int = 32 }, .{ .exact_signed_int = 32 }, .any },
27727 .patterns = &.{
27728 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27729 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27730 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27731 },
27732 .extra_temps = .{
27733 .{ .type = .i32, .kind = .{ .reg = .edx } },
27734 .unused,
27735 .unused,
27736 .unused,
27737 .unused,
27738 .unused,
27739 .unused,
27740 .unused,
27741 .unused,
27742 .unused,
27743 .unused,
27744 },
27745 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27746 .clobbers = .{ .eflags = true },
27747 .each = .{ .once = &.{
27748 .{ ._, .i_, .mul, .src1d, ._, ._, ._ },
27749 .{ ._, ._nc, .j, .@"0f", ._, ._, ._ },
27750 .{ ._, ._, .mov, .dst0d, .tmp0d, ._, ._ },
27751 .{ ._, ._r, .sa, .dst0d, .ui(31), ._, ._ },
27752 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
27753 } },
27754 }, .{
27755 .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
27756 .patterns = &.{
27757 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27758 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27759 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27760 },
27761 .extra_temps = .{
27762 .{ .type = .i32, .kind = .{ .reg = .edx } },
27763 .{ .type = .i32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27764 .unused,
27765 .unused,
27766 .unused,
27767 .unused,
27768 .unused,
27769 .unused,
27770 .unused,
27771 .unused,
27772 .unused,
27773 },
27774 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27775 .clobbers = .{ .eflags = true },
27776 .each = .{ .once = &.{
27777 .{ ._, .i_, .mul, .src1d, ._, ._, ._ },
27778 .{ ._, ._c, .j, .@"1f", ._, ._, ._ },
27779 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27780 .{ ._, ._r, .sa, .tmp1d, .sia(-1, .src0, .add_bit_size), ._, ._ },
27781 .{ ._, ._, .cmp, .tmp1d, .tmp0d, ._, ._ },
27782 .{ ._, ._e, .j, .@"0f", ._, ._, ._ },
27783 .{ .@"1:", ._, .mov, .dst0d, .tmp0d, ._, ._ },
27784 .{ ._, ._r, .sa, .dst0d, .ui(31), ._, ._ },
27785 .{ ._, ._, .xor, .dst0d, .sa(.src0, .add_smax), ._, ._ },
27786 } },
27787 }, .{
27788 .src_constraints = .{ .{ .exact_unsigned_int = 32 }, .{ .exact_unsigned_int = 32 }, .any },
27789 .patterns = &.{
27790 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27791 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27792 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27793 },
27794 .extra_temps = .{
27795 .{ .type = .u32, .kind = .{ .reg = .edx } },
27796 .unused,
27797 .unused,
27798 .unused,
27799 .unused,
27800 .unused,
27801 .unused,
27802 .unused,
27803 .unused,
27804 .unused,
27805 .unused,
27806 },
27807 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27808 .clobbers = .{ .eflags = true },
27809 .each = .{ .once = &.{
27810 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27811 .{ ._, ._, .sbb, .tmp0d, .tmp0d, ._, ._ },
27812 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
27813 } },
27814 }, .{
27815 .required_features = .{ .bmi, .cmov, null, null },
27816 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
27817 .patterns = &.{
27818 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27819 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27820 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27821 },
27822 .extra_temps = .{
27823 .{ .type = .u32, .kind = .{ .reg = .edx } },
27824 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
27825 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27826 .unused,
27827 .unused,
27828 .unused,
27829 .unused,
27830 .unused,
27831 .unused,
27832 .unused,
27833 .unused,
27834 },
27835 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27836 .clobbers = .{ .eflags = true },
27837 .each = .{ .once = &.{
27838 .{ ._, ._, .mov, .tmp1d, .ua(.src0, .add_umax), ._, ._ },
27839 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27840 .{ ._, ._, .andn, .tmp2d, .tmp1d, .dst0d, ._ },
27841 .{ ._, ._, .@"or", .tmp2d, .tmp0d, ._, ._ },
27842 .{ ._, ._nz, .cmov, .dst0d, .tmp1d, ._, ._ },
27843 } },
27844 }, .{
27845 .required_features = .{ .cmov, null, null, null },
27846 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
27847 .patterns = &.{
27848 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27849 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27850 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27851 },
27852 .extra_temps = .{
27853 .{ .type = .u32, .kind = .{ .reg = .edx } },
27854 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27855 .unused,
27856 .unused,
27857 .unused,
27858 .unused,
27859 .unused,
27860 .unused,
27861 .unused,
27862 .unused,
27863 .unused,
27864 },
27865 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27866 .clobbers = .{ .eflags = true },
27867 .each = .{ .once = &.{
27868 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27869 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27870 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27871 .{ ._, ._, .@"or", .tmp1d, .tmp0d, ._, ._ },
27872 .{ ._, ._, .mov, .tmp0d, .ua(.src0, .add_umax), ._, ._ },
27873 .{ ._, ._nz, .cmov, .dst0d, .tmp0d, ._, ._ },
27874 } },
27875 }, .{
27876 .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
27877 .patterns = &.{
27878 .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
27879 .{ .src = .{ .mem, .{ .to_reg = .eax }, .none }, .commute = .{ 0, 1 } },
27880 .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
27881 },
27882 .extra_temps = .{
27883 .{ .type = .u32, .kind = .{ .reg = .edx } },
27884 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .general_purpose } } },
27885 .unused,
27886 .unused,
27887 .unused,
27888 .unused,
27889 .unused,
27890 .unused,
27891 .unused,
27892 .unused,
27893 .unused,
27894 },
27895 .dst_temps = .{ .{ .ref = .src0 }, .unused },
27896 .clobbers = .{ .eflags = true },
27897 .each = .{ .once = &.{
27898 .{ ._, ._, .mul, .src1d, ._, ._, ._ },
27899 .{ ._, ._, .mov, .tmp1d, .dst0d, ._, ._ },
27900 .{ ._, ._, .@"and", .tmp1d, .sa(.src0, .add_2_smin), ._, ._ },
27901 .{ ._, ._, .@"or", .tmp1d, .tmp0d, ._, ._ },
27902 .{ ._, ._z, .j, .@"0f", ._, ._, ._ },
27903 .{ ._, ._, .mov, .dst0d, .ua(.src0, .add_umax), ._, ._ },
27904 } },
27905 }, .{
27906 .required_features = .{ .@"64bit", null, null, null },
27907 .src_constraints = .{ .{ .exact_signed_int = 64 }, .{ .exact_signed_int = 64 }, .any },
27908 .patterns = &.{
27909 .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
27910 .{ .src = .{ .mem, .{ .to_reg = .rax }, .none }, .commute = .{ 0, 1 } },
27911 .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
27912 },
27913 .extra_temps = .{
27914 .{ .type = .i64, .kind = .{ .reg = .rdx } },
27444 .{ .type = .i64, .kind = .{ .reg = .rdx } },
2791527445 .unused,
2791627446 .unused,
2791727447 .unused,
......@@ -33431,6 +32961,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3343132961 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
3343232962 } },
3343332963 }, .{
32964 .required_cc_abi = .sysv64,
3343432965 .required_features = .{ .sse, null, null, null },
3343532966 .src_constraints = .{
3343632967 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -33464,6 +32995,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3346432995 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
3346532996 } },
3346632997 }, .{
32998 .required_cc_abi = .win64,
32999 .required_features = .{ .sse, null, null, null },
33000 .src_constraints = .{
33001 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
33002 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
33003 .any,
33004 },
33005 .patterns = &.{
33006 .{ .src = .{ .to_mem, .to_mem, .none } },
33007 },
33008 .call_frame = .{ .alignment = .@"16" },
33009 .extra_temps = .{
33010 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33011 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
33012 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33013 .unused,
33014 .unused,
33015 .unused,
33016 .unused,
33017 .unused,
33018 .unused,
33019 .unused,
33020 .unused,
33021 },
33022 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
33023 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
33024 .each = .{ .once = &.{
33025 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
33026 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
33027 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
33028 } },
33029 }, .{
33030 .required_cc_abi = .sysv64,
3346733031 .required_features = .{ .avx, null, null, null },
3346833032 .src_constraints = .{
3346933033 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -33475,7 +33039,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3347533039 },
3347633040 .call_frame = .{ .alignment = .@"16" },
3347733041 .extra_temps = .{
33478 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33042 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3347933043 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3348033044 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3348133045 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -33490,15 +33054,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3349033054 .dst_temps = .{ .mem, .unused },
3349133055 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3349233056 .each = .{ .once = &.{
33493 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
33494 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
33495 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
33057 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33058 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
33059 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3349633060 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33497 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
33498 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
33499 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
33061 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
33062 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33063 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3350033064 } },
3350133065 }, .{
33066 .required_cc_abi = .sysv64,
3350233067 .required_features = .{ .sse2, null, null, null },
3350333068 .src_constraints = .{
3350433069 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -33510,7 +33075,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3351033075 },
3351133076 .call_frame = .{ .alignment = .@"16" },
3351233077 .extra_temps = .{
33513 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33078 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3351433079 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3351533080 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3351633081 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -33525,15 +33090,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3352533090 .dst_temps = .{ .mem, .unused },
3352633091 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3352733092 .each = .{ .once = &.{
33528 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
33529 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
33530 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
33093 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33094 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
33095 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3353133096 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33532 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
33533 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
33534 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
33097 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
33098 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33099 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3353533100 } },
3353633101 }, .{
33102 .required_cc_abi = .sysv64,
3353733103 .required_features = .{ .sse, null, null, null },
3353833104 .src_constraints = .{
3353933105 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -33545,7 +33111,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3354533111 },
3354633112 .call_frame = .{ .alignment = .@"16" },
3354733113 .extra_temps = .{
33548 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
33114 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3354933115 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3355033116 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3355133117 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -33560,13 +33126,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3356033126 .dst_temps = .{ .mem, .unused },
3356133127 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3356233128 .each = .{ .once = &.{
33563 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
33564 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
33565 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
33129 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33130 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
33131 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3356633132 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33567 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
33568 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
33569 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
33133 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
33134 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33135 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
33136 } },
33137 }, .{
33138 .required_cc_abi = .win64,
33139 .required_features = .{ .avx, null, null, null },
33140 .src_constraints = .{
33141 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33142 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33143 .any,
33144 },
33145 .patterns = &.{
33146 .{ .src = .{ .to_mem, .to_mem, .none } },
33147 },
33148 .call_frame = .{ .alignment = .@"16" },
33149 .extra_temps = .{
33150 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
33151 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33152 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
33153 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33154 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33155 .unused,
33156 .unused,
33157 .unused,
33158 .unused,
33159 .unused,
33160 .unused,
33161 },
33162 .dst_temps = .{ .mem, .unused },
33163 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
33164 .each = .{ .once = &.{
33165 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33166 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
33167 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
33168 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33169 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
33170 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33171 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
33172 } },
33173 }, .{
33174 .required_cc_abi = .win64,
33175 .required_features = .{ .sse2, null, null, null },
33176 .src_constraints = .{
33177 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33178 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33179 .any,
33180 },
33181 .patterns = &.{
33182 .{ .src = .{ .to_mem, .to_mem, .none } },
33183 },
33184 .call_frame = .{ .alignment = .@"16" },
33185 .extra_temps = .{
33186 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
33187 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33188 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
33189 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33190 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33191 .unused,
33192 .unused,
33193 .unused,
33194 .unused,
33195 .unused,
33196 .unused,
33197 },
33198 .dst_temps = .{ .mem, .unused },
33199 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
33200 .each = .{ .once = &.{
33201 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33202 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
33203 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
33204 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33205 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
33206 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33207 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
33208 } },
33209 }, .{
33210 .required_cc_abi = .win64,
33211 .required_features = .{ .sse, null, null, null },
33212 .src_constraints = .{
33213 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33214 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
33215 .any,
33216 },
33217 .patterns = &.{
33218 .{ .src = .{ .to_mem, .to_mem, .none } },
33219 },
33220 .call_frame = .{ .alignment = .@"16" },
33221 .extra_temps = .{
33222 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
33223 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33224 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
33225 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
33226 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
33227 .unused,
33228 .unused,
33229 .unused,
33230 .unused,
33231 .unused,
33232 .unused,
33233 },
33234 .dst_temps = .{ .mem, .unused },
33235 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
33236 .each = .{ .once = &.{
33237 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
33238 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
33239 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
33240 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
33241 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
33242 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
33243 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3357033244 } },
3357133245 } }) else err: {
3357233246 assert(air_tag == .div_exact);
......@@ -34659,6 +34333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3465934333 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
3466034334 } },
3466134335 }, .{
34336 .required_cc_abi = .sysv64,
3466234337 .required_features = .{ .sse, null, null, null },
3466334338 .src_constraints = .{
3466434339 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -34693,6 +34368,112 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3469334368 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
3469434369 } },
3469534370 }, .{
34371 .required_cc_abi = .win64,
34372 .required_features = .{ .avx, null, null, null },
34373 .src_constraints = .{
34374 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34375 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34376 .any,
34377 },
34378 .patterns = &.{
34379 .{ .src = .{ .to_mem, .to_mem, .none } },
34380 },
34381 .call_frame = .{ .alignment = .@"16" },
34382 .extra_temps = .{
34383 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34384 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34385 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34386 .{ .type = .f128, .kind = .mem },
34387 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34388 .unused,
34389 .unused,
34390 .unused,
34391 .unused,
34392 .unused,
34393 .unused,
34394 },
34395 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
34396 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34397 .each = .{ .once = &.{
34398 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
34399 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
34400 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
34401 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
34402 .{ ._, .v_dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
34403 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34404 } },
34405 }, .{
34406 .required_cc_abi = .win64,
34407 .required_features = .{ .sse2, null, null, null },
34408 .src_constraints = .{
34409 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34410 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34411 .any,
34412 },
34413 .patterns = &.{
34414 .{ .src = .{ .to_mem, .to_mem, .none } },
34415 },
34416 .call_frame = .{ .alignment = .@"16" },
34417 .extra_temps = .{
34418 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34419 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34420 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34421 .{ .type = .f128, .kind = .mem },
34422 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34423 .unused,
34424 .unused,
34425 .unused,
34426 .unused,
34427 .unused,
34428 .unused,
34429 },
34430 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
34431 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34432 .each = .{ .once = &.{
34433 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
34434 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
34435 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
34436 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
34437 .{ ._, ._dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
34438 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34439 } },
34440 }, .{
34441 .required_cc_abi = .win64,
34442 .required_features = .{ .sse, null, null, null },
34443 .src_constraints = .{
34444 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34445 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
34446 .any,
34447 },
34448 .patterns = &.{
34449 .{ .src = .{ .to_mem, .to_mem, .none } },
34450 },
34451 .call_frame = .{ .alignment = .@"16" },
34452 .extra_temps = .{
34453 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34454 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34455 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34456 .{ .type = .f128, .kind = .mem },
34457 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34458 .unused,
34459 .unused,
34460 .unused,
34461 .unused,
34462 .unused,
34463 .unused,
34464 },
34465 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
34466 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34467 .each = .{ .once = &.{
34468 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
34469 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
34470 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
34471 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
34472 .{ ._, ._ps, .mova, .lea(.tmp0x), .dst0x, ._, ._ },
34473 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34474 } },
34475 }, .{
34476 .required_cc_abi = .sysv64,
3469634477 .required_features = .{ .avx, null, null, null },
3469734478 .src_constraints = .{
3469834479 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -34704,7 +34485,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3470434485 },
3470534486 .call_frame = .{ .alignment = .@"16" },
3470634487 .extra_temps = .{
34707 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34488 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3470834489 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3470934490 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3471034491 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -34719,16 +34500,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3471934500 .dst_temps = .{ .mem, .unused },
3472034501 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3472134502 .each = .{ .once = &.{
34722 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
34723 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
34724 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
34503 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34504 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
34505 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3472534506 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3472634507 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34727 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
34728 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
34729 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
34508 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
34509 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34510 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3473034511 } },
3473134512 }, .{
34513 .required_cc_abi = .sysv64,
3473234514 .required_features = .{ .sse2, null, null, null },
3473334515 .src_constraints = .{
3473434516 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -34740,7 +34522,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3474034522 },
3474134523 .call_frame = .{ .alignment = .@"16" },
3474234524 .extra_temps = .{
34743 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34525 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3474434526 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3474534527 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3474634528 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -34755,16 +34537,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3475534537 .dst_temps = .{ .mem, .unused },
3475634538 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3475734539 .each = .{ .once = &.{
34758 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
34759 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
34760 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
34540 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34541 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
34542 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3476134543 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3476234544 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34763 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
34764 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
34765 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
34545 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
34546 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34547 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3476634548 } },
3476734549 }, .{
34550 .required_cc_abi = .sysv64,
3476834551 .required_features = .{ .sse, null, null, null },
3476934552 .src_constraints = .{
3477034553 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -34776,7 +34559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3477634559 },
3477734560 .call_frame = .{ .alignment = .@"16" },
3477834561 .extra_temps = .{
34779 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
34562 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3478034563 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3478134564 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3478234565 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -34791,14 +34574,131 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3479134574 .dst_temps = .{ .mem, .unused },
3479234575 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3479334576 .each = .{ .once = &.{
34794 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
34795 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
34796 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
34577 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34578 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
34579 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3479734580 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3479834581 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
34799 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
34800 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
34801 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
34582 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
34583 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34584 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
34585 } },
34586 }, .{
34587 .required_cc_abi = .win64,
34588 .required_features = .{ .avx, null, null, null },
34589 .src_constraints = .{
34590 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34591 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34592 .any,
34593 },
34594 .patterns = &.{
34595 .{ .src = .{ .to_mem, .to_mem, .none } },
34596 },
34597 .call_frame = .{ .alignment = .@"16" },
34598 .extra_temps = .{
34599 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
34600 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34601 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34602 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34603 .{ .type = .f128, .kind = .mem },
34604 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34605 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34606 .unused,
34607 .unused,
34608 .unused,
34609 .unused,
34610 },
34611 .dst_temps = .{ .mem, .unused },
34612 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34613 .each = .{ .once = &.{
34614 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34615 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
34616 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
34617 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
34618 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
34619 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
34620 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
34621 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
34622 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34623 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
34624 } },
34625 }, .{
34626 .required_cc_abi = .win64,
34627 .required_features = .{ .sse2, null, null, null },
34628 .src_constraints = .{
34629 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34630 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34631 .any,
34632 },
34633 .patterns = &.{
34634 .{ .src = .{ .to_mem, .to_mem, .none } },
34635 },
34636 .call_frame = .{ .alignment = .@"16" },
34637 .extra_temps = .{
34638 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
34639 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34640 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34641 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34642 .{ .type = .f128, .kind = .mem },
34643 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34644 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34645 .unused,
34646 .unused,
34647 .unused,
34648 .unused,
34649 },
34650 .dst_temps = .{ .mem, .unused },
34651 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34652 .each = .{ .once = &.{
34653 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34654 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
34655 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
34656 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
34657 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
34658 .{ ._, ._dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
34659 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
34660 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
34661 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34662 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
34663 } },
34664 }, .{
34665 .required_cc_abi = .win64,
34666 .required_features = .{ .sse, null, null, null },
34667 .src_constraints = .{
34668 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34669 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
34670 .any,
34671 },
34672 .patterns = &.{
34673 .{ .src = .{ .to_mem, .to_mem, .none } },
34674 },
34675 .call_frame = .{ .alignment = .@"16" },
34676 .extra_temps = .{
34677 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
34678 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34679 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
34680 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
34681 .{ .type = .f128, .kind = .mem },
34682 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
34683 .{ .type = .usize, .kind = .{ .extern_func = "truncq" } },
34684 .unused,
34685 .unused,
34686 .unused,
34687 .unused,
34688 },
34689 .dst_temps = .{ .mem, .unused },
34690 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
34691 .each = .{ .once = &.{
34692 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
34693 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
34694 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
34695 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
34696 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
34697 .{ ._, ._ps, .mova, .lea(.tmp1x), .tmp5x, ._, ._ },
34698 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
34699 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
34700 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
34701 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3480234702 } },
3480334703 } }) else err: {
3480434704 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
......@@ -35955,6 +35855,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3595535855 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
3595635856 } },
3595735857 }, .{
35858 .required_cc_abi = .sysv64,
3595835859 .required_features = .{ .sse, null, null, null },
3595935860 .src_constraints = .{
3596035861 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -35993,6 +35894,124 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3599335894 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
3599435895 } },
3599535896 }, .{
35897 .required_cc_abi = .win64,
35898 .required_features = .{ .avx, null, null, null },
35899 .src_constraints = .{
35900 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35901 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35902 .any,
35903 },
35904 .patterns = &.{
35905 .{ .src = .{ .to_mem, .to_mem, .none } },
35906 },
35907 .call_frame = .{ .alignment = .@"16" },
35908 .extra_temps = .{
35909 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
35910 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
35911 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35912 .{ .type = .f128, .kind = .mem },
35913 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35914 else => unreachable,
35915 .zero => "truncq",
35916 .down => "floorq",
35917 } } },
35918 .unused,
35919 .unused,
35920 .unused,
35921 .unused,
35922 .unused,
35923 .unused,
35924 },
35925 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
35926 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
35927 .each = .{ .once = &.{
35928 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
35929 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
35930 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
35931 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
35932 .{ ._, .v_dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
35933 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
35934 } },
35935 }, .{
35936 .required_cc_abi = .win64,
35937 .required_features = .{ .sse2, null, null, null },
35938 .src_constraints = .{
35939 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35940 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35941 .any,
35942 },
35943 .patterns = &.{
35944 .{ .src = .{ .to_mem, .to_mem, .none } },
35945 },
35946 .call_frame = .{ .alignment = .@"16" },
35947 .extra_temps = .{
35948 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
35949 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
35950 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35951 .{ .type = .f128, .kind = .mem },
35952 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35953 else => unreachable,
35954 .zero => "truncq",
35955 .down => "floorq",
35956 } } },
35957 .unused,
35958 .unused,
35959 .unused,
35960 .unused,
35961 .unused,
35962 .unused,
35963 },
35964 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
35965 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
35966 .each = .{ .once = &.{
35967 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
35968 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
35969 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
35970 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
35971 .{ ._, ._dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
35972 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
35973 } },
35974 }, .{
35975 .required_cc_abi = .win64,
35976 .required_features = .{ .sse, null, null, null },
35977 .src_constraints = .{
35978 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35979 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
35980 .any,
35981 },
35982 .patterns = &.{
35983 .{ .src = .{ .to_mem, .to_mem, .none } },
35984 },
35985 .call_frame = .{ .alignment = .@"16" },
35986 .extra_temps = .{
35987 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
35988 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
35989 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
35990 .{ .type = .f128, .kind = .mem },
35991 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
35992 else => unreachable,
35993 .zero => "truncq",
35994 .down => "floorq",
35995 } } },
35996 .unused,
35997 .unused,
35998 .unused,
35999 .unused,
36000 .unused,
36001 .unused,
36002 },
36003 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
36004 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
36005 .each = .{ .once = &.{
36006 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
36007 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
36008 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
36009 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
36010 .{ ._, ._ps, .mova, .lea(.tmp0x), .dst0x, ._, ._ },
36011 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
36012 } },
36013 }, .{
36014 .required_cc_abi = .sysv64,
3599636015 .required_features = .{ .avx, null, null, null },
3599736016 .src_constraints = .{
3599836017 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -36004,7 +36023,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3600436023 },
3600536024 .call_frame = .{ .alignment = .@"16" },
3600636025 .extra_temps = .{
36007 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36026 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3600836027 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3600936028 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3601036029 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -36023,16 +36042,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3602336042 .dst_temps = .{ .mem, .unused },
3602436043 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3602536044 .each = .{ .once = &.{
36026 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
36027 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
36028 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
36045 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36046 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
36047 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3602936048 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3603036049 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
36031 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
36032 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
36033 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
36050 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
36051 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36052 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3603436053 } },
3603536054 }, .{
36055 .required_cc_abi = .sysv64,
3603636056 .required_features = .{ .sse2, null, null, null },
3603736057 .src_constraints = .{
3603836058 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -36044,7 +36064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3604436064 },
3604536065 .call_frame = .{ .alignment = .@"16" },
3604636066 .extra_temps = .{
36047 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36067 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3604836068 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3604936069 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3605036070 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -36063,16 +36083,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3606336083 .dst_temps = .{ .mem, .unused },
3606436084 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3606536085 .each = .{ .once = &.{
36066 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
36067 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
36068 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
36086 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36087 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
36088 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3606936089 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3607036090 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
36071 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
36072 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
36073 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
36091 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
36092 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36093 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3607436094 } },
3607536095 }, .{
36096 .required_cc_abi = .sysv64,
3607636097 .required_features = .{ .sse, null, null, null },
3607736098 .src_constraints = .{
3607836099 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -36084,7 +36105,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3608436105 },
3608536106 .call_frame = .{ .alignment = .@"16" },
3608636107 .extra_temps = .{
36087 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
36108 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3608836109 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3608936110 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3609036111 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -36103,14 +36124,143 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3610336124 .dst_temps = .{ .mem, .unused },
3610436125 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3610536126 .each = .{ .once = &.{
36106 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
36107 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
36108 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
36127 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36128 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
36129 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3610936130 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3611036131 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
36111 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
36112 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
36113 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
36132 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
36133 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36134 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
36135 } },
36136 }, .{
36137 .required_cc_abi = .win64,
36138 .required_features = .{ .avx, null, null, null },
36139 .src_constraints = .{
36140 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36141 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36142 .any,
36143 },
36144 .patterns = &.{
36145 .{ .src = .{ .to_mem, .to_mem, .none } },
36146 },
36147 .call_frame = .{ .alignment = .@"16" },
36148 .extra_temps = .{
36149 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
36150 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36151 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
36152 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36153 .{ .type = .f128, .kind = .mem },
36154 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36155 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36156 else => unreachable,
36157 .zero => "truncq",
36158 .down => "floorq",
36159 } } },
36160 .unused,
36161 .unused,
36162 .unused,
36163 .unused,
36164 },
36165 .dst_temps = .{ .mem, .unused },
36166 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
36167 .each = .{ .once = &.{
36168 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36169 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
36170 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
36171 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
36172 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
36173 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
36174 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
36175 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
36176 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36177 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
36178 } },
36179 }, .{
36180 .required_cc_abi = .win64,
36181 .required_features = .{ .sse2, null, null, null },
36182 .src_constraints = .{
36183 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36184 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36185 .any,
36186 },
36187 .patterns = &.{
36188 .{ .src = .{ .to_mem, .to_mem, .none } },
36189 },
36190 .call_frame = .{ .alignment = .@"16" },
36191 .extra_temps = .{
36192 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
36193 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36194 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
36195 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36196 .{ .type = .f128, .kind = .mem },
36197 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36198 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36199 else => unreachable,
36200 .zero => "truncq",
36201 .down => "floorq",
36202 } } },
36203 .unused,
36204 .unused,
36205 .unused,
36206 .unused,
36207 },
36208 .dst_temps = .{ .mem, .unused },
36209 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
36210 .each = .{ .once = &.{
36211 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36212 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
36213 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
36214 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
36215 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
36216 .{ ._, ._dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
36217 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
36218 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
36219 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36220 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
36221 } },
36222 }, .{
36223 .required_cc_abi = .win64,
36224 .required_features = .{ .sse, null, null, null },
36225 .src_constraints = .{
36226 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36227 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
36228 .any,
36229 },
36230 .patterns = &.{
36231 .{ .src = .{ .to_mem, .to_mem, .none } },
36232 },
36233 .call_frame = .{ .alignment = .@"16" },
36234 .extra_temps = .{
36235 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
36236 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36237 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
36238 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
36239 .{ .type = .f128, .kind = .mem },
36240 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
36241 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
36242 else => unreachable,
36243 .zero => "truncq",
36244 .down => "floorq",
36245 } } },
36246 .unused,
36247 .unused,
36248 .unused,
36249 .unused,
36250 },
36251 .dst_temps = .{ .mem, .unused },
36252 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
36253 .each = .{ .once = &.{
36254 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
36255 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
36256 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
36257 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
36258 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
36259 .{ ._, ._ps, .mova, .lea(.tmp1x), .tmp5x, ._, ._ },
36260 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
36261 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
36262 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
36263 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3611436264 } },
3611536265 } },
3611636266 }) catch |err| switch (err) {
......@@ -37438,6 +37588,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3743837588 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
3743937589 } },
3744037590 }, .{
37591 .required_cc_abi = .sysv64,
3744137592 .required_features = .{ .sse, null, null, null },
3744237593 .src_constraints = .{
3744337594 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -37472,6 +37623,112 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3747237623 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
3747337624 } },
3747437625 }, .{
37626 .required_cc_abi = .win64,
37627 .required_features = .{ .avx, null, null, null },
37628 .src_constraints = .{
37629 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37630 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37631 .any,
37632 },
37633 .patterns = &.{
37634 .{ .src = .{ .to_mem, .to_mem, .none } },
37635 },
37636 .call_frame = .{ .alignment = .@"16" },
37637 .extra_temps = .{
37638 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37639 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37640 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37641 .{ .type = .f128, .kind = .mem },
37642 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37643 .unused,
37644 .unused,
37645 .unused,
37646 .unused,
37647 .unused,
37648 .unused,
37649 },
37650 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
37651 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37652 .each = .{ .once = &.{
37653 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
37654 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
37655 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
37656 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
37657 .{ ._, .v_dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
37658 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37659 } },
37660 }, .{
37661 .required_cc_abi = .win64,
37662 .required_features = .{ .sse2, null, null, null },
37663 .src_constraints = .{
37664 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37665 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37666 .any,
37667 },
37668 .patterns = &.{
37669 .{ .src = .{ .to_mem, .to_mem, .none } },
37670 },
37671 .call_frame = .{ .alignment = .@"16" },
37672 .extra_temps = .{
37673 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37674 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37675 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37676 .{ .type = .f128, .kind = .mem },
37677 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37678 .unused,
37679 .unused,
37680 .unused,
37681 .unused,
37682 .unused,
37683 .unused,
37684 },
37685 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
37686 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37687 .each = .{ .once = &.{
37688 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
37689 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
37690 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
37691 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
37692 .{ ._, ._dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
37693 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37694 } },
37695 }, .{
37696 .required_cc_abi = .win64,
37697 .required_features = .{ .sse, null, null, null },
37698 .src_constraints = .{
37699 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37700 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
37701 .any,
37702 },
37703 .patterns = &.{
37704 .{ .src = .{ .to_mem, .to_mem, .none } },
37705 },
37706 .call_frame = .{ .alignment = .@"16" },
37707 .extra_temps = .{
37708 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37709 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37710 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37711 .{ .type = .f128, .kind = .mem },
37712 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37713 .unused,
37714 .unused,
37715 .unused,
37716 .unused,
37717 .unused,
37718 .unused,
37719 },
37720 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
37721 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37722 .each = .{ .once = &.{
37723 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
37724 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
37725 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
37726 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
37727 .{ ._, ._ps, .mova, .lea(.tmp0x), .dst0x, ._, ._ },
37728 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37729 } },
37730 }, .{
37731 .required_cc_abi = .sysv64,
3747537732 .required_features = .{ .avx, null, null, null },
3747637733 .src_constraints = .{
3747737734 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -37483,7 +37740,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3748337740 },
3748437741 .call_frame = .{ .alignment = .@"16" },
3748537742 .extra_temps = .{
37486 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37743 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3748737744 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3748837745 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3748937746 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -37498,16 +37755,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3749837755 .dst_temps = .{ .mem, .unused },
3749937756 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3750037757 .each = .{ .once = &.{
37501 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
37502 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
37503 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
37758 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37759 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
37760 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3750437761 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3750537762 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37506 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
37507 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
37508 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
37763 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
37764 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37765 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3750937766 } },
3751037767 }, .{
37768 .required_cc_abi = .sysv64,
3751137769 .required_features = .{ .sse2, null, null, null },
3751237770 .src_constraints = .{
3751337771 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -37519,7 +37777,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3751937777 },
3752037778 .call_frame = .{ .alignment = .@"16" },
3752137779 .extra_temps = .{
37522 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37780 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3752337781 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3752437782 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3752537783 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -37534,16 +37792,17 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3753437792 .dst_temps = .{ .mem, .unused },
3753537793 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3753637794 .each = .{ .once = &.{
37537 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
37538 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
37539 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
37795 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37796 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
37797 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3754037798 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3754137799 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37542 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
37543 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
37544 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
37800 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
37801 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37802 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3754537803 } },
3754637804 }, .{
37805 .required_cc_abi = .sysv64,
3754737806 .required_features = .{ .sse, null, null, null },
3754837807 .src_constraints = .{
3754937808 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -37555,7 +37814,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3755537814 },
3755637815 .call_frame = .{ .alignment = .@"16" },
3755737816 .extra_temps = .{
37558 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
37817 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3755937818 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3756037819 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3756137820 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
......@@ -37570,14 +37829,131 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3757037829 .dst_temps = .{ .mem, .unused },
3757137830 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3757237831 .each = .{ .once = &.{
37573 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
37574 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
37575 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
37832 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37833 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
37834 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3757637835 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
3757737836 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
37578 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
37579 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
37580 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
37837 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
37838 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37839 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
37840 } },
37841 }, .{
37842 .required_cc_abi = .win64,
37843 .required_features = .{ .avx, null, null, null },
37844 .src_constraints = .{
37845 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37846 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37847 .any,
37848 },
37849 .patterns = &.{
37850 .{ .src = .{ .to_mem, .to_mem, .none } },
37851 },
37852 .call_frame = .{ .alignment = .@"16" },
37853 .extra_temps = .{
37854 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
37855 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37856 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37857 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37858 .{ .type = .f128, .kind = .mem },
37859 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37860 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37861 .unused,
37862 .unused,
37863 .unused,
37864 .unused,
37865 },
37866 .dst_temps = .{ .mem, .unused },
37867 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37868 .each = .{ .once = &.{
37869 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37870 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
37871 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
37872 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
37873 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
37874 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
37875 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
37876 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
37877 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37878 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
37879 } },
37880 }, .{
37881 .required_cc_abi = .win64,
37882 .required_features = .{ .sse2, null, null, null },
37883 .src_constraints = .{
37884 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37885 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37886 .any,
37887 },
37888 .patterns = &.{
37889 .{ .src = .{ .to_mem, .to_mem, .none } },
37890 },
37891 .call_frame = .{ .alignment = .@"16" },
37892 .extra_temps = .{
37893 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
37894 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37895 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37896 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37897 .{ .type = .f128, .kind = .mem },
37898 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37899 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37900 .unused,
37901 .unused,
37902 .unused,
37903 .unused,
37904 },
37905 .dst_temps = .{ .mem, .unused },
37906 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37907 .each = .{ .once = &.{
37908 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37909 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
37910 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
37911 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
37912 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
37913 .{ ._, ._dqa, .mov, .lea(.tmp1x), .tmp5x, ._, ._ },
37914 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
37915 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
37916 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37917 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
37918 } },
37919 }, .{
37920 .required_cc_abi = .win64,
37921 .required_features = .{ .sse, null, null, null },
37922 .src_constraints = .{
37923 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37924 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
37925 .any,
37926 },
37927 .patterns = &.{
37928 .{ .src = .{ .to_mem, .to_mem, .none } },
37929 },
37930 .call_frame = .{ .alignment = .@"16" },
37931 .extra_temps = .{
37932 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
37933 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37934 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
37935 .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } },
37936 .{ .type = .f128, .kind = .mem },
37937 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
37938 .{ .type = .usize, .kind = .{ .extern_func = "floorq" } },
37939 .unused,
37940 .unused,
37941 .unused,
37942 .unused,
37943 },
37944 .dst_temps = .{ .mem, .unused },
37945 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
37946 .each = .{ .once = &.{
37947 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
37948 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0x, .tmp0), ._, ._ },
37949 .{ ._, ._, .lea, .tmp2p, .memi(.src1x, .tmp0), ._, ._ },
37950 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
37951 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
37952 .{ ._, ._ps, .mova, .lea(.tmp1x), .tmp5x, ._, ._ },
37953 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
37954 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
37955 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
37956 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3758137957 } },
3758237958 } })) catch |err| switch (err) {
3758337959 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -39080,6 +39456,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3908039456 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
3908139457 } },
3908239458 }, .{
39459 .required_cc_abi = .sysv64,
3908339460 .required_features = .{ .sse, null, null, null },
3908439461 .src_constraints = .{
3908539462 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -39113,6 +39490,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3911339490 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
3911439491 } },
3911539492 }, .{
39493 .required_cc_abi = .win64,
39494 .required_features = .{ .sse, null, null, null },
39495 .src_constraints = .{
39496 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
39497 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
39498 .any,
39499 },
39500 .patterns = &.{
39501 .{ .src = .{ .to_mem, .to_mem, .none } },
39502 },
39503 .call_frame = .{ .alignment = .@"16" },
39504 .extra_temps = .{
39505 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39506 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39507 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
39508 .unused,
39509 .unused,
39510 .unused,
39511 .unused,
39512 .unused,
39513 .unused,
39514 .unused,
39515 .unused,
39516 },
39517 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
39518 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
39519 .each = .{ .once = &.{
39520 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
39521 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
39522 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
39523 } },
39524 }, .{
39525 .required_cc_abi = .sysv64,
3911639526 .required_features = .{ .avx, null, null, null },
3911739527 .src_constraints = .{
3911839528 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -39124,7 +39534,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3912439534 },
3912539535 .call_frame = .{ .alignment = .@"16" },
3912639536 .extra_temps = .{
39127 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
39537 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3912839538 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3912939539 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3913039540 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
......@@ -39139,15 +39549,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3913939549 .dst_temps = .{ .mem, .unused },
3914039550 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3914139551 .each = .{ .once = &.{
39142 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
39143 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
39144 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
39552 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39553 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
39554 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3914539555 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39146 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
39147 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
39148 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
39556 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
39557 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39558 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3914939559 } },
3915039560 }, .{
39561 .required_cc_abi = .sysv64,
3915139562 .required_features = .{ .sse2, null, null, null },
3915239563 .src_constraints = .{
3915339564 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -39159,7 +39570,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3915939570 },
3916039571 .call_frame = .{ .alignment = .@"16" },
3916139572 .extra_temps = .{
39162 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
39573 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3916339574 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3916439575 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3916539576 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
......@@ -39174,15 +39585,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3917439585 .dst_temps = .{ .mem, .unused },
3917539586 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3917639587 .each = .{ .once = &.{
39177 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
39178 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
39179 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
39588 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39589 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
39590 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3918039591 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39181 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
39182 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
39183 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
39592 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
39593 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39594 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3918439595 } },
3918539596 }, .{
39597 .required_cc_abi = .sysv64,
3918639598 .required_features = .{ .sse, null, null, null },
3918739599 .src_constraints = .{
3918839600 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -39194,7 +39606,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3919439606 },
3919539607 .call_frame = .{ .alignment = .@"16" },
3919639608 .extra_temps = .{
39197 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
39609 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
3919839610 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
3919939611 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
3920039612 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
......@@ -39209,13 +39621,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3920939621 .dst_temps = .{ .mem, .unused },
3921039622 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3921139623 .each = .{ .once = &.{
39212 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
39213 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
39214 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
39624 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39625 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
39626 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
3921539627 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39216 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
39217 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
39218 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
39628 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
39629 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39630 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
39631 } },
39632 }, .{
39633 .required_cc_abi = .win64,
39634 .required_features = .{ .avx, null, null, null },
39635 .src_constraints = .{
39636 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39637 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39638 .any,
39639 },
39640 .patterns = &.{
39641 .{ .src = .{ .to_mem, .to_mem, .none } },
39642 },
39643 .call_frame = .{ .alignment = .@"16" },
39644 .extra_temps = .{
39645 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39646 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39647 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39648 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
39649 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39650 .unused,
39651 .unused,
39652 .unused,
39653 .unused,
39654 .unused,
39655 .unused,
39656 },
39657 .dst_temps = .{ .mem, .unused },
39658 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
39659 .each = .{ .once = &.{
39660 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39661 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
39662 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
39663 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39664 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
39665 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39666 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
39667 } },
39668 }, .{
39669 .required_cc_abi = .win64,
39670 .required_features = .{ .sse2, null, null, null },
39671 .src_constraints = .{
39672 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39673 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39674 .any,
39675 },
39676 .patterns = &.{
39677 .{ .src = .{ .to_mem, .to_mem, .none } },
39678 },
39679 .call_frame = .{ .alignment = .@"16" },
39680 .extra_temps = .{
39681 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39682 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39683 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39684 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
39685 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39686 .unused,
39687 .unused,
39688 .unused,
39689 .unused,
39690 .unused,
39691 .unused,
39692 },
39693 .dst_temps = .{ .mem, .unused },
39694 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
39695 .each = .{ .once = &.{
39696 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39697 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
39698 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
39699 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39700 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
39701 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39702 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
39703 } },
39704 }, .{
39705 .required_cc_abi = .win64,
39706 .required_features = .{ .sse, null, null, null },
39707 .src_constraints = .{
39708 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39709 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
39710 .any,
39711 },
39712 .patterns = &.{
39713 .{ .src = .{ .to_mem, .to_mem, .none } },
39714 },
39715 .call_frame = .{ .alignment = .@"16" },
39716 .extra_temps = .{
39717 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
39718 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39719 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39720 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
39721 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39722 .unused,
39723 .unused,
39724 .unused,
39725 .unused,
39726 .unused,
39727 .unused,
39728 },
39729 .dst_temps = .{ .mem, .unused },
39730 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
39731 .each = .{ .once = &.{
39732 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
39733 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
39734 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
39735 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
39736 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
39737 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
39738 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3921939739 } },
3922039740 } }) catch |err| switch (err) {
3922139741 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -39525,7 +40045,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3952540045 } },
3952640046 }, .{
3952740047 .required_cc_abi = .sysv64,
39528 .required_features = .{ .cmov, null, null, null },
40048 .required_features = .{ .@"64bit", .cmov, null, null },
3952940049 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
3953040050 .patterns = &.{
3953140051 .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .to_mem, .none } },
......@@ -39565,6 +40085,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3956540085 } },
3956640086 }, .{
3956740087 .required_cc_abi = .sysv64,
40088 .required_features = .{ .@"64bit", null, null, null },
3956840089 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
3956940090 .patterns = &.{
3957040091 .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .to_mem, .none } },
......@@ -39601,70 +40122,344 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3960140122 .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ },
3960240123 } },
3960340124 }, .{
39604 .required_cc_abi = .sysv64,
39605 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
40125 .required_cc_abi = .win64,
40126 .required_features = .{ .@"64bit", .cmov, .avx, null },
40127 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
3960640128 .patterns = &.{
39607 .{ .src = .{
39608 .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } },
39609 .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 2, .at = 2 } },
39610 .none,
39611 } },
40129 .{ .src = .{ .to_mem, .to_mem, .none } },
3961240130 },
3961340131 .call_frame = .{ .alignment = .@"16" },
3961440132 .extra_temps = .{
39615 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
40133 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40134 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40135 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40136 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40137 .{ .type = .u64, .kind = .{ .reg = .rax } },
40138 .{ .type = .u64, .kind = .{ .reg = .r10 } },
3961640139 .unused,
3961740140 .unused,
3961840141 .unused,
3961940142 .unused,
3962040143 .unused,
40144 },
40145 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40146 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40147 .each = .{ .once = &.{
40148 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40149 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40150 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40151 .{ ._, .v_q, .mov, .dst0q0, .tmp1x, ._, ._ },
40152 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40153 .{ ._, .vp_q, .extr, .dst0q1, .tmp1x, .ui(1), ._ },
40154 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40155 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40156 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40157 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40158 .{ ._, ._, .xor, .tmp5d, .tmp5d, ._, ._ },
40159 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40160 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40161 .{ ._, ._nae, .cmov, .tmp2q, .tmp5q, ._, ._ },
40162 .{ ._, ._ae, .cmov, .tmp5q, .mem(.src1q), ._, ._ },
40163 .{ ._, ._, .add, .dst0q0, .tmp5q, ._, ._ },
40164 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
40165 } },
40166 }, .{
40167 .required_cc_abi = .win64,
40168 .required_features = .{ .@"64bit", .cmov, .sse4_1, null },
40169 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40170 .patterns = &.{
40171 .{ .src = .{ .to_mem, .to_mem, .none } },
40172 },
40173 .call_frame = .{ .alignment = .@"16" },
40174 .extra_temps = .{
40175 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40176 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40177 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40178 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40179 .{ .type = .u64, .kind = .{ .reg = .rax } },
40180 .{ .type = .u64, .kind = .{ .reg = .r10 } },
3962140181 .unused,
3962240182 .unused,
3962340183 .unused,
3962440184 .unused,
3962540185 .unused,
3962640186 },
39627 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40187 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
3962840188 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3962940189 .each = .{ .once = &.{
40190 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40191 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
3963040192 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40193 .{ ._, ._q, .mov, .dst0q0, .tmp1x, ._, ._ },
40194 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40195 .{ ._, .p_q, .extr, .dst0q1, .tmp1x, .ui(1), ._ },
40196 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40197 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40198 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40199 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40200 .{ ._, ._, .xor, .tmp5d, .tmp5d, ._, ._ },
40201 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40202 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40203 .{ ._, ._nae, .cmov, .tmp2q, .tmp5q, ._, ._ },
40204 .{ ._, ._ae, .cmov, .tmp5q, .mem(.src1q), ._, ._ },
40205 .{ ._, ._, .add, .dst0q0, .tmp5q, ._, ._ },
40206 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
3963140207 } },
3963240208 }, .{
3963340209 .required_cc_abi = .win64,
39634 .required_features = .{ .sse, null, null, null },
39635 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
40210 .required_features = .{ .@"64bit", .cmov, .sse2, null },
40211 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
3963640212 .patterns = &.{
3963740213 .{ .src = .{ .to_mem, .to_mem, .none } },
3963840214 },
3963940215 .call_frame = .{ .alignment = .@"16" },
3964040216 .extra_temps = .{
39641 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
39642 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
39643 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
40217 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40218 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40219 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40220 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40221 .{ .type = .u64, .kind = .{ .reg = .rax } },
40222 .{ .type = .u64, .kind = .{ .reg = .r10 } },
3964440223 .unused,
3964540224 .unused,
3964640225 .unused,
3964740226 .unused,
3964840227 .unused,
40228 },
40229 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40230 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40231 .each = .{ .once = &.{
40232 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40233 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40234 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40235 .{ ._, ._q, .mov, .dst0q0, .tmp1x, ._, ._ },
40236 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40237 .{ ._, .p_d, .shuf, .tmp1x, .tmp1x, .ui(0b11_10_11_10), ._ },
40238 .{ ._, ._q, .mov, .dst0q1, .tmp1x, ._, ._ },
40239 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40240 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40241 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40242 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40243 .{ ._, ._, .xor, .tmp5d, .tmp5d, ._, ._ },
40244 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40245 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40246 .{ ._, ._nae, .cmov, .tmp2q, .tmp5q, ._, ._ },
40247 .{ ._, ._ae, .cmov, .tmp5q, .mem(.src1q), ._, ._ },
40248 .{ ._, ._, .add, .dst0q0, .tmp5q, ._, ._ },
40249 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
40250 } },
40251 }, .{
40252 .required_cc_abi = .win64,
40253 .required_features = .{ .@"64bit", .cmov, .sse, null },
40254 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40255 .patterns = &.{
40256 .{ .src = .{ .to_mem, .to_mem, .none } },
40257 },
40258 .call_frame = .{ .alignment = .@"16" },
40259 .extra_temps = .{
40260 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40261 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40262 .{ .type = .i128, .kind = .mem },
40263 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40264 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40265 .{ .type = .u64, .kind = .{ .reg = .rax } },
40266 .{ .type = .u64, .kind = .{ .reg = .r10 } },
40267 .unused,
3964940268 .unused,
3965040269 .unused,
3965140270 .unused,
3965240271 },
39653 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40272 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
3965440273 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3965540274 .each = .{ .once = &.{
39656 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
39657 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
39658 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
40275 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40276 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40277 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40278 .{ ._, ._ps, .mova, .mem(.tmp2x), .tmp1x, ._, ._ },
40279 .{ ._, ._, .mov, .tmp3q, .memd(.src1q, 8), ._, ._ },
40280 .{ ._, ._, .mov, .dst0q0, .mem(.tmp2q), ._, ._ },
40281 .{ ._, ._, .mov, .dst0q1, .memd(.tmp2q, 8), ._, ._ },
40282 .{ ._, ._, .mov, .tmp4q, .ua(.src0, .add_smin), ._, ._ },
40283 .{ ._, ._, .mov, .tmp5q, .tmp3q, ._, ._ },
40284 .{ ._, ._, .@"and", .tmp5q, .tmp4q, ._, ._ },
40285 .{ ._, ._, .xor, .tmp5q, .dst0q1, ._, ._ },
40286 .{ ._, ._, .xor, .tmp6d, .tmp6d, ._, ._ },
40287 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40288 .{ ._, ._, .sbb, .tmp5q, .tmp4q, ._, ._ },
40289 .{ ._, ._nae, .cmov, .tmp3q, .tmp6q, ._, ._ },
40290 .{ ._, ._ae, .cmov, .tmp6q, .mem(.src1q), ._, ._ },
40291 .{ ._, ._, .add, .dst0q0, .tmp6q, ._, ._ },
40292 .{ ._, ._, .adc, .dst0q1, .tmp3q, ._, ._ },
3965940293 } },
3966040294 }, .{
3966140295 .required_cc_abi = .win64,
39662 .required_features = .{ .sse, null, null, null },
40296 .required_features = .{ .@"64bit", .avx, null, null },
40297 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40298 .patterns = &.{
40299 .{ .src = .{ .to_mem, .to_mem, .none } },
40300 },
40301 .call_frame = .{ .alignment = .@"16" },
40302 .extra_temps = .{
40303 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40304 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40305 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40306 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40307 .{ .type = .u64, .kind = .{ .reg = .rax } },
40308 .unused,
40309 .unused,
40310 .unused,
40311 .unused,
40312 .unused,
40313 .unused,
40314 },
40315 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40316 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40317 .each = .{ .once = &.{
40318 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40319 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40320 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40321 .{ ._, .v_q, .mov, .dst0q0, .tmp1x, ._, ._ },
40322 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40323 .{ ._, .vp_q, .extr, .dst0q1, .tmp1x, .ui(1), ._ },
40324 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40325 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40326 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40327 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40328 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40329 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40330 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
40331 .{ ._, ._, .add, .dst0q0, .mem(.src1x), ._, ._ },
40332 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
40333 } },
40334 }, .{
40335 .required_cc_abi = .win64,
40336 .required_features = .{ .@"64bit", .sse4_1, null, null },
40337 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40338 .patterns = &.{
40339 .{ .src = .{ .to_mem, .to_mem, .none } },
40340 },
40341 .call_frame = .{ .alignment = .@"16" },
40342 .extra_temps = .{
40343 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40344 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40345 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40346 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40347 .{ .type = .u64, .kind = .{ .reg = .rax } },
40348 .unused,
40349 .unused,
40350 .unused,
40351 .unused,
40352 .unused,
40353 .unused,
40354 },
40355 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40356 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40357 .each = .{ .once = &.{
40358 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40359 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40360 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40361 .{ ._, ._q, .mov, .dst0q0, .tmp1x, ._, ._ },
40362 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40363 .{ ._, .p_q, .extr, .dst0q1, .tmp1x, .ui(1), ._ },
40364 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40365 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40366 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40367 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40368 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40369 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40370 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
40371 .{ ._, ._, .add, .dst0q0, .mem(.src1x), ._, ._ },
40372 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
40373 } },
40374 }, .{
40375 .required_cc_abi = .win64,
40376 .required_features = .{ .@"64bit", .sse2, null, null },
40377 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40378 .patterns = &.{
40379 .{ .src = .{ .to_mem, .to_mem, .none } },
40380 },
40381 .call_frame = .{ .alignment = .@"16" },
40382 .extra_temps = .{
40383 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40384 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40385 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40386 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40387 .{ .type = .u64, .kind = .{ .reg = .rax } },
40388 .unused,
40389 .unused,
40390 .unused,
40391 .unused,
40392 .unused,
40393 .unused,
40394 },
40395 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40396 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40397 .each = .{ .once = &.{
40398 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40399 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40400 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40401 .{ ._, ._q, .mov, .dst0q0, .tmp1x, ._, ._ },
40402 .{ ._, ._, .mov, .tmp2q, .memd(.src1q, 8), ._, ._ },
40403 .{ ._, .p_d, .shuf, .tmp1x, .tmp1x, .ui(0b11_10_11_10), ._ },
40404 .{ ._, ._q, .mov, .dst0q1, .tmp1x, ._, ._ },
40405 .{ ._, ._, .mov, .tmp3q, .ua(.src0, .add_smin), ._, ._ },
40406 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
40407 .{ ._, ._, .@"and", .tmp4q, .tmp3q, ._, ._ },
40408 .{ ._, ._, .xor, .tmp4q, .dst0q1, ._, ._ },
40409 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40410 .{ ._, ._, .sbb, .tmp4q, .tmp3q, ._, ._ },
40411 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
40412 .{ ._, ._, .add, .dst0q0, .mem(.src1x), ._, ._ },
40413 .{ ._, ._, .adc, .dst0q1, .tmp2q, ._, ._ },
40414 } },
40415 }, .{
40416 .required_cc_abi = .win64,
40417 .required_features = .{ .@"64bit", .sse, null, null },
40418 .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
40419 .patterns = &.{
40420 .{ .src = .{ .to_mem, .to_mem, .none } },
40421 },
40422 .call_frame = .{ .alignment = .@"16" },
40423 .extra_temps = .{
40424 .{ .type = .usize, .kind = .{ .extern_func = "__modti3" } },
40425 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40426 .{ .type = .i128, .kind = .mem },
40427 .{ .type = .u64, .kind = .{ .reg = .r8 } },
40428 .{ .type = .u64, .kind = .{ .reg = .r9 } },
40429 .{ .type = .u64, .kind = .{ .reg = .rax } },
40430 .unused,
40431 .unused,
40432 .unused,
40433 .unused,
40434 .unused,
40435 },
40436 .dst_temps = .{ .{ .param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40437 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40438 .each = .{ .once = &.{
40439 .{ ._, ._, .lea, .dst0q0, .mem(.src0), ._, ._ },
40440 .{ ._, ._, .lea, .dst0q1, .mem(.src1), ._, ._ },
40441 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
40442 .{ ._, ._ps, .mova, .mem(.tmp2x), .tmp1x, ._, ._ },
40443 .{ ._, ._, .mov, .tmp3q, .memd(.src1q, 8), ._, ._ },
40444 .{ ._, ._, .mov, .dst0q0, .mem(.tmp2q), ._, ._ },
40445 .{ ._, ._, .mov, .dst0q1, .memd(.tmp2q, 8), ._, ._ },
40446 .{ ._, ._, .mov, .tmp4q, .ua(.src0, .add_smin), ._, ._ },
40447 .{ ._, ._, .mov, .tmp5q, .tmp3q, ._, ._ },
40448 .{ ._, ._, .@"and", .tmp5q, .tmp4q, ._, ._ },
40449 .{ ._, ._, .xor, .tmp5q, .dst0q1, ._, ._ },
40450 .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
40451 .{ ._, ._, .sbb, .tmp5q, .tmp4q, ._, ._ },
40452 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
40453 .{ ._, ._, .add, .dst0q0, .mem(.src1x), ._, ._ },
40454 .{ ._, ._, .adc, .dst0q1, .tmp3q, ._, ._ },
40455 } },
40456 }, .{
40457 .required_cc_abi = .sysv64,
3966340458 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
3966440459 .patterns = &.{
3966540460 .{ .src = .{
39666 .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } },
39667 .{ .to_param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } },
40461 .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } },
40462 .{ .to_param_gpr_pair = .{ .cc = .ccc, .after = 2, .at = 2 } },
3966840463 .none,
3966940464 } },
3967040465 },
......@@ -39682,11 +40477,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3968240477 .unused,
3968340478 .unused,
3968440479 },
39685 .dst_temps = .{ .{ .ref = .src0 }, .unused },
40480 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
3968640481 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
3968740482 .each = .{ .once = &.{
3968840483 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
3968940484 } },
40485 }, .{
40486 .required_cc_abi = .win64,
40487 .required_features = .{ .sse, null, null, null },
40488 .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
40489 .patterns = &.{
40490 .{ .src = .{ .to_mem, .to_mem, .none } },
40491 },
40492 .call_frame = .{ .alignment = .@"16" },
40493 .extra_temps = .{
40494 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
40495 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
40496 .{ .type = .usize, .kind = .{ .extern_func = "__umodti3" } },
40497 .unused,
40498 .unused,
40499 .unused,
40500 .unused,
40501 .unused,
40502 .unused,
40503 .unused,
40504 .unused,
40505 },
40506 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
40507 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
40508 .each = .{ .once = &.{
40509 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
40510 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
40511 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
40512 } },
3969040513 }, .{
3969140514 .required_features = .{ .@"64bit", null, null, null },
3969240515 .src_constraints = .{
......@@ -41082,8 +41905,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4108241905 .{ .type = .f64, .kind = .{ .reg = .rdx } },
4108341906 .{ .type = .f64, .kind = .mem },
4108441907 .{ .type = .f64, .kind = .{ .reg = .rax } },
41085 .{ .type = .f64, .kind = .{ .reg = .st6 } },
4108641908 .{ .type = .f64, .kind = .{ .reg = .st7 } },
41909 .{ .type = .f64, .kind = .{ .reg = .st6 } },
4108741910 .unused,
4108841911 .unused,
4108941912 },
......@@ -41130,13 +41953,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4113041953 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4113141954 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4113241955 .{ .type = .f80, .kind = .{ .reg = .st7 } },
41956 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4113341957 .{ .type = .f80, .kind = .{ .reg = .rax } },
4113441958 .unused,
4113541959 .unused,
4113641960 .unused,
4113741961 .unused,
4113841962 .unused,
41139 .unused,
4114041963 },
4114141964 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4114241965 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41145,17 +41968,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4114541968 .{ ._, .v_dqa, .mov, .mem(.tmp1x), .tmp0x, ._, ._ },
4114641969 .{ ._, .v_dqa, .mov, .tmp0x, .mem(.src1x), ._, ._ },
4114741970 .{ ._, .v_dqa, .mov, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
41971 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4114841972 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41149 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
41973 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4115041974 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41151 .{ ._, ._, .movzx, .tmp4d, .memd(.tmp1w, 16 + 8), ._, ._ },
41152 .{ ._, ._, .@"and", .tmp4w, .sa(.src0, .add_smin), ._, ._ },
41153 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
41975 .{ ._, ._, .movzx, .tmp5d, .memd(.src1w, 8), ._, ._ },
41976 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
41977 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4115441978 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41155 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
41979 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4115641980 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41157 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
41981 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
4115841982 .{ ._, .f_p, .add, ._, ._, ._, ._ },
41983 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4115941984 } },
4116041985 }, .{
4116141986 .required_abi = .gnu,
......@@ -41175,13 +42000,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4117542000 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4117642001 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4117742002 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42003 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4117842004 .{ .type = .f80, .kind = .{ .reg = .rax } },
4117942005 .unused,
4118042006 .unused,
4118142007 .unused,
4118242008 .unused,
4118342009 .unused,
41184 .unused,
4118542010 },
4118642011 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4118742012 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41191,16 +42016,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4119142016 .{ ._, .v_dqa, .mov, .tmp0x, .mem(.src1x), ._, ._ },
4119242017 .{ ._, .v_dqa, .mov, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
4119342018 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41194 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
42019 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
42020 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4119542021 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41196 .{ ._, ._, .mov, .tmp4d, .sa(.src0, .add_smin), ._, ._ },
41197 .{ ._, ._, .@"and", .tmp4w, .memd(.tmp1w, 16 + 8), ._, ._ },
41198 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
42022 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
42023 .{ ._, ._, .@"and", .tmp5w, .memd(.src1w, 8), ._, ._ },
42024 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4119942025 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41200 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
42026 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4120142027 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41202 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
42028 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
4120342029 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42030 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4120442031 } },
4120542032 }, .{
4120642033 .required_abi = .gnu,
......@@ -41220,13 +42047,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4122042047 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4122142048 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4122242049 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42050 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4122342051 .{ .type = .f80, .kind = .{ .reg = .rax } },
4122442052 .unused,
4122542053 .unused,
4122642054 .unused,
4122742055 .unused,
4122842056 .unused,
41229 .unused,
4123042057 },
4123142058 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4123242059 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41236,16 +42063,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4123642063 .{ ._, ._dqa, .mov, .tmp0x, .mem(.src1x), ._, ._ },
4123742064 .{ ._, ._dqa, .mov, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
4123842065 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41239 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
42066 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
42067 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4124042068 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41241 .{ ._, ._, .movzx, .tmp4d, .memd(.tmp1w, 16 + 8), ._, ._ },
41242 .{ ._, ._, .@"and", .tmp4w, .sa(.src0, .add_smin), ._, ._ },
41243 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
42069 .{ ._, ._, .movzx, .tmp5d, .memd(.src1w, 8), ._, ._ },
42070 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42071 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4124442072 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41245 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
42073 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4124642074 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41247 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
42075 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
4124842076 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42077 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4124942078 } },
4125042079 }, .{
4125142080 .required_abi = .gnu,
......@@ -41265,13 +42094,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4126542094 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4126642095 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4126742096 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42097 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4126842098 .{ .type = .f80, .kind = .{ .reg = .rax } },
4126942099 .unused,
4127042100 .unused,
4127142101 .unused,
4127242102 .unused,
4127342103 .unused,
41274 .unused,
4127542104 },
4127642105 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4127742106 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41281,16 +42110,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4128142110 .{ ._, ._dqa, .mov, .tmp0x, .mem(.src1x), ._, ._ },
4128242111 .{ ._, ._dqa, .mov, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
4128342112 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41284 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
42113 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
42114 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4128542115 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41286 .{ ._, ._, .mov, .tmp4d, .sa(.src0, .add_smin), ._, ._ },
41287 .{ ._, ._, .@"and", .tmp4w, .memd(.tmp1w, 16 + 8), ._, ._ },
41288 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
42116 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
42117 .{ ._, ._, .@"and", .tmp5w, .memd(.src1w, 8), ._, ._ },
42118 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4128942119 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41290 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
42120 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4129142121 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41292 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
42122 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
4129342123 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42124 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4129442125 } },
4129542126 }, .{
4129642127 .required_abi = .gnu,
......@@ -41310,13 +42141,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4131042141 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4131142142 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4131242143 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42144 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4131342145 .{ .type = .f80, .kind = .{ .reg = .rax } },
4131442146 .unused,
4131542147 .unused,
4131642148 .unused,
4131742149 .unused,
4131842150 .unused,
41319 .unused,
4132042151 },
4132142152 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4132242153 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41326,16 +42157,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4132642157 .{ ._, ._ps, .mova, .tmp0x, .mem(.src1x), ._, ._ },
4132742158 .{ ._, ._ps, .mova, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
4132842159 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41329 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
42160 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
42161 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4133042162 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41331 .{ ._, ._, .movzx, .tmp4d, .memd(.tmp1w, 16 + 8), ._, ._ },
41332 .{ ._, ._, .@"and", .tmp4w, .sa(.src0, .add_smin), ._, ._ },
41333 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
42163 .{ ._, ._, .movzx, .tmp5d, .memd(.src1w, 8), ._, ._ },
42164 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42165 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4133442166 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41335 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
42167 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4133642168 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41337 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
42169 .{ ._, .f_, .ld, .memd(.src1t, 16), ._, ._, ._ },
4133842170 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42171 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4133942172 } },
4134042173 }, .{
4134142174 .required_abi = .gnu,
......@@ -41355,13 +42188,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4135542188 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4135642189 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4135742190 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42191 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4135842192 .{ .type = .f80, .kind = .{ .reg = .rax } },
4135942193 .unused,
4136042194 .unused,
4136142195 .unused,
4136242196 .unused,
4136342197 .unused,
41364 .unused,
4136542198 },
4136642199 .dst_temps = .{ .{ .reg = .st0 }, .unused },
4136742200 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41371,16 +42204,106 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4137142204 .{ ._, ._ps, .mova, .tmp0x, .mem(.src1x), ._, ._ },
4137242205 .{ ._, ._ps, .mova, .memd(.tmp1x, 16), .tmp0x, ._, ._ },
4137342206 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
41374 .{ ._, .f_, .ld, .dst0t, ._, ._, ._ },
42207 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
42208 .{ ._, .f_, .ld, .tmp3t, ._, ._, ._ },
4137542209 .{ ._, .f_p, .st, .mem(.tmp1t), ._, ._, ._ },
41376 .{ ._, ._, .mov, .tmp4d, .sa(.src0, .add_smin), ._, ._ },
41377 .{ ._, ._, .@"and", .tmp4w, .memd(.tmp1w, 16 + 8), ._, ._ },
41378 .{ ._, ._, .xor, .tmp4w, .memd(.tmp1w, 8), ._, ._ },
42210 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
42211 .{ ._, ._, .@"and", .tmp5w, .memd(.src1w, 8), ._, ._ },
42212 .{ ._, ._, .xor, .tmp5w, .memd(.tmp1w, 8), ._, ._ },
4137942213 .{ ._, ._, .cmp, .mem(.tmp1q), .si(1), ._, ._ },
41380 .{ ._, ._, .sbb, .tmp4w, .sa(.src0, .add_smin), ._, ._ },
42214 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
4138142215 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
41382 .{ ._, .f_, .ld, .memd(.tmp1t, 16), ._, ._, ._ },
42216 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
4138342217 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42218 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
42219 } },
42220 }, .{
42221 .required_abi = .gnu,
42222 .required_cc_abi = .win64,
42223 .required_features = .{ .@"64bit", .x87, .fast_imm16, null },
42224 .src_constraints = .{
42225 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
42226 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
42227 .any,
42228 },
42229 .patterns = &.{
42230 .{ .src = .{ .to_mem, .to_mem, .none } },
42231 },
42232 .call_frame = .{ .alignment = .@"16" },
42233 .extra_temps = .{
42234 .{ .type = .f80, .kind = .mem },
42235 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42236 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42237 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
42238 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
42239 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42240 .{ .type = .f80, .kind = .{ .reg = .st6 } },
42241 .{ .type = .f80, .kind = .{ .reg = .rax } },
42242 .unused,
42243 .unused,
42244 .unused,
42245 },
42246 .dst_temps = .{ .{ .reg = .st0 }, .unused },
42247 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42248 .each = .{ .once = &.{
42249 .{ ._, ._, .lea, .tmp1p, .mem(.tmp0), ._, ._ },
42250 .{ ._, ._, .lea, .tmp2p, .mem(.src0), ._, ._ },
42251 .{ ._, ._, .lea, .tmp3p, .mem(.src1), ._, ._ },
42252 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
42253 .{ ._, .f_, .ld, .mem(.tmp0t), ._, ._, ._ },
42254 .{ ._, ._, .movzx, .tmp7d, .memd(.src1w, 8), ._, ._ },
42255 .{ ._, ._, .@"and", .tmp7w, .sa(.src0, .add_smin), ._, ._ },
42256 .{ ._, ._, .xor, .tmp7w, .memd(.tmp0w, 8), ._, ._ },
42257 .{ ._, ._, .cmp, .mem(.tmp0q), .si(1), ._, ._ },
42258 .{ ._, ._, .sbb, .tmp7w, .sa(.src0, .add_smin), ._, ._ },
42259 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
42260 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
42261 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42262 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
42263 } },
42264 }, .{
42265 .required_abi = .gnu,
42266 .required_cc_abi = .win64,
42267 .required_features = .{ .@"64bit", .x87, null, null },
42268 .src_constraints = .{
42269 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
42270 .{ .scalar_float = .{ .of = .xword, .is = .tbyte } },
42271 .any,
42272 },
42273 .patterns = &.{
42274 .{ .src = .{ .to_mem, .to_mem, .none } },
42275 },
42276 .call_frame = .{ .alignment = .@"16" },
42277 .extra_temps = .{
42278 .{ .type = .f80, .kind = .mem },
42279 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42280 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42281 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
42282 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
42283 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42284 .{ .type = .f80, .kind = .{ .reg = .st6 } },
42285 .{ .type = .f80, .kind = .{ .reg = .rax } },
42286 .unused,
42287 .unused,
42288 .unused,
42289 },
42290 .dst_temps = .{ .{ .reg = .st0 }, .unused },
42291 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42292 .each = .{ .once = &.{
42293 .{ ._, ._, .lea, .tmp1p, .mem(.tmp0), ._, ._ },
42294 .{ ._, ._, .lea, .tmp2p, .mem(.src0), ._, ._ },
42295 .{ ._, ._, .lea, .tmp3p, .mem(.src1), ._, ._ },
42296 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
42297 .{ ._, .f_, .ld, .mem(.tmp0t), ._, ._, ._ },
42298 .{ ._, ._, .mov, .tmp7d, .sa(.src0, .add_smin), ._, ._ },
42299 .{ ._, ._, .@"and", .tmp7w, .memd(.src1w, 8), ._, ._ },
42300 .{ ._, ._, .xor, .tmp7w, .memd(.tmp0w, 8), ._, ._ },
42301 .{ ._, ._, .cmp, .mem(.tmp0q), .si(1), ._, ._ },
42302 .{ ._, ._, .sbb, .tmp7w, .sa(.src0, .add_smin), ._, ._ },
42303 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
42304 .{ ._, .f_, .ld, .mem(.src1t), ._, ._, ._ },
42305 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42306 .{ .pseudo, .f_cstp, .in, ._, ._, ._, ._ },
4138442307 } },
4138542308 }, .{
4138642309 .required_abi = .gnu,
......@@ -41401,12 +42324,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4140142324 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4140242325 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4140342326 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42327 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4140442328 .{ .type = .f80, .kind = .{ .reg = .rax } },
4140542329 .unused,
4140642330 .unused,
4140742331 .unused,
4140842332 .unused,
41409 .unused,
4141042333 },
4141142334 .dst_temps = .{ .mem, .unused },
4141242335 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41420,13 +42343,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4142042343 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4142142344 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4142242345 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41423 .{ ._, ._, .movzx, .tmp5d, .memd(.tmp2w, 16 + 8), ._, ._ },
41424 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
41425 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42346 .{ ._, ._, .movzx, .tmp6d, .memid(.src1w, .tmp0, 8), ._, ._ },
42347 .{ ._, ._, .@"and", .tmp6w, .sa(.src0, .add_smin), ._, ._ },
42348 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4142642349 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41427 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42350 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4142842351 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41429 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42352 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4143042353 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4143142354 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4143242355 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
......@@ -41451,12 +42374,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4145142374 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4145242375 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4145342376 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42377 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4145442378 .{ .type = .f80, .kind = .{ .reg = .rax } },
4145542379 .unused,
4145642380 .unused,
4145742381 .unused,
4145842382 .unused,
41459 .unused,
4146042383 },
4146142384 .dst_temps = .{ .mem, .unused },
4146242385 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41470,13 +42393,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4147042393 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4147142394 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4147242395 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41473 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
41474 .{ ._, ._, .@"and", .tmp5w, .memd(.tmp2w, 16 + 8), ._, ._ },
41475 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42396 .{ ._, ._, .mov, .tmp6d, .sa(.src0, .add_smin), ._, ._ },
42397 .{ ._, ._, .@"and", .tmp6w, .memid(.src1w, .tmp0, 8), ._, ._ },
42398 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4147642399 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41477 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42400 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4147842401 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41479 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42402 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4148042403 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4148142404 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4148242405 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
......@@ -41501,12 +42424,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4150142424 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4150242425 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4150342426 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42427 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4150442428 .{ .type = .f80, .kind = .{ .reg = .rax } },
4150542429 .unused,
4150642430 .unused,
4150742431 .unused,
4150842432 .unused,
41509 .unused,
4151042433 },
4151142434 .dst_temps = .{ .mem, .unused },
4151242435 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41520,13 +42443,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4152042443 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4152142444 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4152242445 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41523 .{ ._, ._, .movzx, .tmp5d, .memd(.tmp2w, 16 + 8), ._, ._ },
41524 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
41525 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42446 .{ ._, ._, .movzx, .tmp6d, .memid(.src1w, .tmp0, 8), ._, ._ },
42447 .{ ._, ._, .@"and", .tmp6w, .sa(.src0, .add_smin), ._, ._ },
42448 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4152642449 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41527 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42450 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4152842451 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41529 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42452 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4153042453 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4153142454 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4153242455 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
......@@ -41551,12 +42474,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4155142474 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4155242475 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4155342476 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42477 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4155442478 .{ .type = .f80, .kind = .{ .reg = .rax } },
4155542479 .unused,
4155642480 .unused,
4155742481 .unused,
4155842482 .unused,
41559 .unused,
4156042483 },
4156142484 .dst_temps = .{ .mem, .unused },
4156242485 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41570,13 +42493,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4157042493 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4157142494 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4157242495 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41573 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
41574 .{ ._, ._, .@"and", .tmp5w, .memd(.tmp2w, 16 + 8), ._, ._ },
41575 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42496 .{ ._, ._, .mov, .tmp6d, .sa(.src0, .add_smin), ._, ._ },
42497 .{ ._, ._, .@"and", .tmp6w, .memid(.src1w, .tmp0, 8), ._, ._ },
42498 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4157642499 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41577 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42500 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4157842501 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41579 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42502 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4158042503 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4158142504 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4158242505 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
......@@ -41601,12 +42524,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4160142524 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4160242525 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4160342526 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42527 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4160442528 .{ .type = .f80, .kind = .{ .reg = .rax } },
4160542529 .unused,
4160642530 .unused,
4160742531 .unused,
4160842532 .unused,
41609 .unused,
4161042533 },
4161142534 .dst_temps = .{ .mem, .unused },
4161242535 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41620,13 +42543,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4162042543 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4162142544 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4162242545 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41623 .{ ._, ._, .movzx, .tmp5d, .memd(.tmp2w, 16 + 8), ._, ._ },
41624 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
41625 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42546 .{ ._, ._, .movzx, .tmp6d, .memid(.src1w, .tmp0, 8), ._, ._ },
42547 .{ ._, ._, .@"and", .tmp6w, .sa(.src0, .add_smin), ._, ._ },
42548 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4162642549 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41627 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42550 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4162842551 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41629 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42552 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4163042553 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4163142554 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4163242555 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
......@@ -41651,12 +42574,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4165142574 .{ .type = .f80, .kind = .{ .frame = .call_frame } },
4165242575 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
4165342576 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42577 .{ .type = .f80, .kind = .{ .reg = .st6 } },
4165442578 .{ .type = .f80, .kind = .{ .reg = .rax } },
4165542579 .unused,
4165642580 .unused,
4165742581 .unused,
4165842582 .unused,
41659 .unused,
4166042583 },
4166142584 .dst_temps = .{ .mem, .unused },
4166242585 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
......@@ -41670,19 +42593,114 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4167042593 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
4167142594 .{ ._, .f_, .ld, .tmp4t, ._, ._, ._ },
4167242595 .{ ._, .f_p, .st, .mem(.tmp2t), ._, ._, ._ },
41673 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
41674 .{ ._, ._, .@"and", .tmp5w, .memd(.tmp2w, 16 + 8), ._, ._ },
41675 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42596 .{ ._, ._, .mov, .tmp6d, .sa(.src0, .add_smin), ._, ._ },
42597 .{ ._, ._, .@"and", .tmp6w, .memid(.src1w, .tmp0, 8), ._, ._ },
42598 .{ ._, ._, .xor, .tmp6w, .memd(.tmp2w, 8), ._, ._ },
4167642599 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
41677 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42600 .{ ._, ._, .sbb, .tmp6w, .sa(.src0, .add_smin), ._, ._ },
4167842601 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
41679 .{ ._, .f_, .ld, .memd(.tmp2t, 16), ._, ._, ._ },
42602 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
4168042603 .{ ._, .f_p, .add, ._, ._, ._, ._ },
4168142604 .{ .@"1:", .f_p, .st, .memia(.dst0t, .tmp0, .add_unaligned_size), ._, ._, ._ },
4168242605 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
4168342606 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4168442607 } },
4168542608 }, .{
42609 .required_abi = .gnu,
42610 .required_cc_abi = .win64,
42611 .required_features = .{ .@"64bit", .sse, .x87, .fast_imm16 },
42612 .src_constraints = .{
42613 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
42614 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
42615 .any,
42616 },
42617 .patterns = &.{
42618 .{ .src = .{ .to_mem, .to_mem, .none } },
42619 },
42620 .call_frame = .{ .alignment = .@"16" },
42621 .extra_temps = .{
42622 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
42623 .{ .type = .usize, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42624 .{ .type = .usize, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42625 .{ .type = .usize, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } },
42626 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
42627 .{ .type = .f80, .kind = .{ .reg = .rax } },
42628 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42629 .{ .type = .f80, .kind = .{ .reg = .st6 } },
42630 .unused,
42631 .unused,
42632 .unused,
42633 },
42634 .dst_temps = .{ .mem, .unused },
42635 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42636 .each = .{ .once = &.{
42637 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
42638 .{ .@"0:", ._, .lea, .tmp1p, .memi(.dst0, .tmp0), ._, ._ },
42639 .{ ._, ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
42640 .{ ._, ._, .lea, .tmp3p, .memi(.src1, .tmp0), ._, ._ },
42641 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
42642 .{ ._, ._, .movzx, .tmp5d, .memid(.src1w, .tmp0, 8), ._, ._ },
42643 .{ ._, ._, .@"and", .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42644 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42645 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
42646 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42647 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
42648 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
42649 .{ ._, .f_, .ld, .memi(.dst0t, .tmp0), ._, ._, ._ },
42650 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42651 .{ ._, .f_p, .st, .memi(.dst0t, .tmp0), ._, ._, ._ },
42652 .{ .@"1:", ._, .sub, .tmp0d, .si(16), ._, ._ },
42653 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
42654 } },
42655 }, .{
42656 .required_abi = .gnu,
42657 .required_cc_abi = .win64,
42658 .required_features = .{ .@"64bit", .sse, .x87, null },
42659 .src_constraints = .{
42660 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
42661 .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } },
42662 .any,
42663 },
42664 .patterns = &.{
42665 .{ .src = .{ .to_mem, .to_mem, .none } },
42666 },
42667 .call_frame = .{ .alignment = .@"16" },
42668 .extra_temps = .{
42669 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
42670 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42671 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42672 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
42673 .{ .type = .usize, .kind = .{ .extern_func = "__fmodx" } },
42674 .{ .type = .f80, .kind = .{ .reg = .rax } },
42675 .{ .type = .f80, .kind = .{ .reg = .st7 } },
42676 .{ .type = .f80, .kind = .{ .reg = .st6 } },
42677 .unused,
42678 .unused,
42679 .unused,
42680 },
42681 .dst_temps = .{ .mem, .unused },
42682 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42683 .each = .{ .once = &.{
42684 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
42685 .{ .@"0:", ._, .lea, .tmp1p, .memi(.dst0, .tmp0), ._, ._ },
42686 .{ ._, ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
42687 .{ ._, ._, .lea, .tmp3p, .memi(.src1, .tmp0), ._, ._ },
42688 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
42689 .{ ._, ._, .mov, .tmp5d, .sa(.src0, .add_smin), ._, ._ },
42690 .{ ._, ._, .@"and", .tmp5w, .memid(.src1w, .tmp0, 8), ._, ._ },
42691 .{ ._, ._, .xor, .tmp5w, .memd(.tmp2w, 8), ._, ._ },
42692 .{ ._, ._, .cmp, .mem(.tmp2q), .si(1), ._, ._ },
42693 .{ ._, ._, .sbb, .tmp5w, .sa(.src0, .add_smin), ._, ._ },
42694 .{ ._, ._nae, .j, .@"1f", ._, ._, ._ },
42695 .{ ._, .f_, .ld, .memi(.src1t, .tmp0), ._, ._, ._ },
42696 .{ ._, .f_, .ld, .memi(.dst0t, .tmp0), ._, ._, ._ },
42697 .{ ._, .f_p, .add, ._, ._, ._, ._ },
42698 .{ ._, .f_p, .st, .memi(.dst0t, .tmp0), ._, ._, ._ },
42699 .{ .@"1:", ._, .sub, .tmp0d, .si(16), ._, ._ },
42700 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
42701 } },
42702 }, .{
42703 .required_cc_abi = .sysv64,
4168642704 .required_features = .{ .@"64bit", .avx, null, null },
4168742705 .src_constraints = .{
4168842706 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41700,9 +42718,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4170042718 .extra_temps = .{
4170142719 .{ .type = .f128, .kind = .mem },
4170242720 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
41703 .{ .type = .f128, .kind = .{ .reg = .rcx } },
41704 .{ .type = .f128, .kind = .{ .reg = .rdx } },
41705 .{ .type = .f128, .kind = .{ .reg = .rax } },
42721 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42722 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42723 .{ .type = .u64, .kind = .{ .reg = .rax } },
4170642724 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4170742725 .unused,
4170842726 .unused,
......@@ -41728,6 +42746,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4172842746 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
4172942747 } },
4173042748 }, .{
42749 .required_cc_abi = .sysv64,
4173142750 .required_features = .{ .@"64bit", .sse4_1, null, null },
4173242751 .src_constraints = .{
4173342752 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41745,9 +42764,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4174542764 .extra_temps = .{
4174642765 .{ .type = .f128, .kind = .mem },
4174742766 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
41748 .{ .type = .f128, .kind = .{ .reg = .rcx } },
41749 .{ .type = .f128, .kind = .{ .reg = .rdx } },
41750 .{ .type = .f128, .kind = .{ .reg = .rax } },
42767 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42768 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42769 .{ .type = .u64, .kind = .{ .reg = .rax } },
4175142770 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4175242771 .unused,
4175342772 .unused,
......@@ -41773,6 +42792,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4177342792 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
4177442793 } },
4177542794 }, .{
42795 .required_cc_abi = .sysv64,
4177642796 .required_features = .{ .@"64bit", .sse2, null, null },
4177742797 .src_constraints = .{
4177842798 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41790,9 +42810,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4179042810 .extra_temps = .{
4179142811 .{ .type = .f128, .kind = .mem },
4179242812 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
41793 .{ .type = .f128, .kind = .{ .reg = .rcx } },
41794 .{ .type = .f128, .kind = .{ .reg = .rdx } },
41795 .{ .type = .f128, .kind = .{ .reg = .rax } },
42813 .{ .type = .u64, .kind = .{ .reg = .rcx } },
42814 .{ .type = .u64, .kind = .{ .reg = .rdx } },
42815 .{ .type = .u64, .kind = .{ .reg = .rax } },
4179642816 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4179742817 .unused,
4179842818 .unused,
......@@ -41805,8 +42825,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4180542825 .each = .{ .once = &.{
4180642826 .{ ._, ._dqa, .mov, .mem(.tmp0x), .src1x, ._, ._ },
4180742827 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
41808 .{ ._, ._, .mov, .tmp2q, .ua(.src0, .add_smin), ._, ._ },
4180942828 .{ ._, .p_d, .shuf, .src1x, .dst0x, .ui(0b11_10_11_10), ._ },
42829 .{ ._, ._, .mov, .tmp2q, .ua(.src0, .add_smin), ._, ._ },
4181042830 .{ ._, ._q, .mov, .tmp3q, .src1x, ._, ._ },
4181142831 .{ ._, ._, .mov, .tmp4q, .tmp2q, ._, ._ },
4181242832 .{ ._, ._, .@"and", .tmp4q, .memd(.tmp0q, 8), ._, ._ },
......@@ -41819,6 +42839,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4181942839 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
4182042840 } },
4182142841 }, .{
42842 .required_cc_abi = .sysv64,
4182242843 .required_features = .{ .@"64bit", .sse, null, null },
4182342844 .src_constraints = .{
4182442845 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41836,9 +42857,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4183642857 .extra_temps = .{
4183742858 .{ .type = .f128, .kind = .mem },
4183842859 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
41839 .{ .type = .f128, .kind = .{ .reg = .rdx } },
42860 .{ .type = .u64, .kind = .{ .reg = .rdx } },
4184042861 .{ .type = .f128, .kind = .mem },
41841 .{ .type = .f128, .kind = .{ .reg = .rax } },
42862 .{ .type = .u64, .kind = .{ .reg = .rax } },
4184242863 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
4184342864 .unused,
4184442865 .unused,
......@@ -41863,6 +42884,186 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4186342884 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
4186442885 } },
4186542886 }, .{
42887 .required_cc_abi = .win64,
42888 .required_features = .{ .@"64bit", .avx, null, null },
42889 .src_constraints = .{
42890 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42891 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42892 .any,
42893 },
42894 .patterns = &.{
42895 .{ .src = .{ .to_mem, .to_mem, .none } },
42896 },
42897 .call_frame = .{ .alignment = .@"16" },
42898 .extra_temps = .{
42899 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42900 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42901 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
42902 .{ .type = .f128, .kind = .mem },
42903 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
42904 .{ .type = .u64, .kind = .{ .reg = .rax } },
42905 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
42906 .unused,
42907 .unused,
42908 .unused,
42909 .unused,
42910 },
42911 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
42912 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42913 .each = .{ .once = &.{
42914 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
42915 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
42916 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
42917 .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
42918 .{ ._, .vp_q, .extr, .tmp1q, .dst0x, .ui(1), ._ },
42919 .{ ._, ._, .mov, .tmp5q, .tmp0q, ._, ._ },
42920 .{ ._, ._, .@"and", .tmp5q, .memd(.src1q, 8), ._, ._ },
42921 .{ ._, ._, .xor, .tmp5q, .tmp1q, ._, ._ },
42922 .{ ._, .v_q, .mov, .tmp1q, .dst0x, ._, ._ },
42923 .{ ._, ._, .cmp, .tmp1q, .si(1), ._, ._ },
42924 .{ ._, ._, .sbb, .tmp5q, .tmp0q, ._, ._ },
42925 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
42926 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
42927 .{ ._, .v_dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
42928 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
42929 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
42930 } },
42931 }, .{
42932 .required_cc_abi = .win64,
42933 .required_features = .{ .@"64bit", .sse4_1, null, null },
42934 .src_constraints = .{
42935 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42936 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42937 .any,
42938 },
42939 .patterns = &.{
42940 .{ .src = .{ .to_mem, .to_mem, .none } },
42941 },
42942 .call_frame = .{ .alignment = .@"16" },
42943 .extra_temps = .{
42944 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42945 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42946 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
42947 .{ .type = .f128, .kind = .mem },
42948 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
42949 .{ .type = .u64, .kind = .{ .reg = .rax } },
42950 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
42951 .unused,
42952 .unused,
42953 .unused,
42954 .unused,
42955 },
42956 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
42957 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
42958 .each = .{ .once = &.{
42959 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
42960 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
42961 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
42962 .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
42963 .{ ._, .p_q, .extr, .tmp1q, .dst0x, .ui(1), ._ },
42964 .{ ._, ._, .mov, .tmp5q, .tmp0q, ._, ._ },
42965 .{ ._, ._, .@"and", .tmp5q, .memd(.src1q, 8), ._, ._ },
42966 .{ ._, ._, .xor, .tmp5q, .tmp1q, ._, ._ },
42967 .{ ._, ._q, .mov, .tmp1q, .dst0x, ._, ._ },
42968 .{ ._, ._, .cmp, .tmp1q, .si(1), ._, ._ },
42969 .{ ._, ._, .sbb, .tmp5q, .tmp0q, ._, ._ },
42970 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
42971 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
42972 .{ ._, ._dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
42973 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
42974 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
42975 } },
42976 }, .{
42977 .required_cc_abi = .win64,
42978 .required_features = .{ .@"64bit", .sse2, null, null },
42979 .src_constraints = .{
42980 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42981 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
42982 .any,
42983 },
42984 .patterns = &.{
42985 .{ .src = .{ .to_mem, .to_mem, .none } },
42986 },
42987 .call_frame = .{ .alignment = .@"16" },
42988 .extra_temps = .{
42989 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
42990 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
42991 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
42992 .{ .type = .f128, .kind = .mem },
42993 .{ .type = .f128, .kind = .{ .reg = .xmm1 } },
42994 .{ .type = .u64, .kind = .{ .reg = .rax } },
42995 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
42996 .unused,
42997 .unused,
42998 .unused,
42999 .unused,
43000 },
43001 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
43002 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
43003 .each = .{ .once = &.{
43004 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
43005 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
43006 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
43007 .{ ._, .p_d, .shuf, .tmp4x, .dst0x, .ui(0b11_10_11_10), ._ },
43008 .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
43009 .{ ._, ._q, .mov, .tmp1q, .tmp4x, ._, ._ },
43010 .{ ._, ._, .mov, .tmp5q, .tmp0q, ._, ._ },
43011 .{ ._, ._, .@"and", .tmp5q, .memd(.src1q, 8), ._, ._ },
43012 .{ ._, ._, .xor, .tmp5q, .tmp1q, ._, ._ },
43013 .{ ._, ._q, .mov, .tmp1q, .dst0x, ._, ._ },
43014 .{ ._, ._, .cmp, .tmp1q, .si(1), ._, ._ },
43015 .{ ._, ._, .sbb, .tmp5q, .tmp0q, ._, ._ },
43016 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
43017 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
43018 .{ ._, ._dqa, .mov, .lea(.tmp0x), .dst0x, ._, ._ },
43019 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
43020 .{ ._, ._, .call, .tmp6d, ._, ._, ._ },
43021 } },
43022 }, .{
43023 .required_cc_abi = .win64,
43024 .required_features = .{ .@"64bit", .sse, null, null },
43025 .src_constraints = .{
43026 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
43027 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
43028 .any,
43029 },
43030 .patterns = &.{
43031 .{ .src = .{ .to_mem, .to_mem, .none } },
43032 },
43033 .call_frame = .{ .alignment = .@"16" },
43034 .extra_temps = .{
43035 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
43036 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
43037 .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } },
43038 .{ .type = .f128, .kind = .mem },
43039 .{ .type = .usize, .kind = .{ .reg = .rax } },
43040 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
43041 .unused,
43042 .unused,
43043 .unused,
43044 .unused,
43045 .unused,
43046 },
43047 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
43048 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
43049 .each = .{ .once = &.{
43050 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
43051 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
43052 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
43053 .{ ._, ._, .lea, .tmp0p, .mem(.tmp3), ._, ._ },
43054 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ },
43055 .{ ._, ._ps, .mova, .lea(.tmp0x), .dst0x, ._, ._ },
43056 .{ ._, ._, .mov, .tmp4q, .tmp1q, ._, ._ },
43057 .{ ._, ._, .@"and", .tmp4q, .memd(.src1q, 8), ._, ._ },
43058 .{ ._, ._, .xor, .tmp4q, .lead(.tmp0q, 8), ._, ._ },
43059 .{ ._, ._, .cmp, .lea(.tmp0q), .si(1), ._, ._ },
43060 .{ ._, ._, .sbb, .tmp4q, .tmp1q, ._, ._ },
43061 .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
43062 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
43063 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
43064 } },
43065 }, .{
43066 .required_cc_abi = .sysv64,
4186643067 .required_features = .{ .@"64bit", .avx, null, null },
4186743068 .src_constraints = .{
4186843069 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41909,6 +43110,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4190943110 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4191043111 } },
4191143112 }, .{
43113 .required_cc_abi = .sysv64,
4191243114 .required_features = .{ .@"64bit", .sse4_1, null, null },
4191343115 .src_constraints = .{
4191443116 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -41955,6 +43157,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4195543157 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4195643158 } },
4195743159 }, .{
43160 .required_cc_abi = .sysv64,
4195843161 .required_features = .{ .@"64bit", .sse2, null, null },
4195943162 .src_constraints = .{
4196043163 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -42002,6 +43205,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4200243205 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4200343206 } },
4200443207 }, .{
43208 .required_cc_abi = .sysv64,
4200543209 .required_features = .{ .@"64bit", .sse, null, null },
4200643210 .src_constraints = .{
4200743211 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -46317,6 +47521,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4631747521 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4631847522 } },
4631947523 }, .{
47524 .required_cc_abi = .sysv64,
4632047525 .required_features = .{ .sse, null, null, null },
4632147526 .src_constraints = .{
4632247527 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -46350,6 +47555,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4635047555 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
4635147556 } },
4635247557 }, .{
47558 .required_cc_abi = .win64,
47559 .required_features = .{ .sse, null, null, null },
47560 .src_constraints = .{
47561 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
47562 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
47563 .any,
47564 },
47565 .patterns = &.{
47566 .{ .src = .{ .to_mem, .to_mem, .none } },
47567 },
47568 .call_frame = .{ .alignment = .@"16" },
47569 .extra_temps = .{
47570 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47571 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47572 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
47573 .unused,
47574 .unused,
47575 .unused,
47576 .unused,
47577 .unused,
47578 .unused,
47579 .unused,
47580 .unused,
47581 },
47582 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
47583 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
47584 .each = .{ .once = &.{
47585 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
47586 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
47587 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
47588 } },
47589 }, .{
47590 .required_cc_abi = .sysv64,
4635347591 .required_features = .{ .avx, null, null, null },
4635447592 .src_constraints = .{
4635547593 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -46361,7 +47599,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4636147599 },
4636247600 .call_frame = .{ .alignment = .@"16" },
4636347601 .extra_temps = .{
46364 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
47602 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4636547603 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4636647604 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4636747605 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
......@@ -46376,15 +47614,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4637647614 .dst_temps = .{ .mem, .unused },
4637747615 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4637847616 .each = .{ .once = &.{
46379 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ },
46380 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ },
46381 .{ ._, .v_dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._, ._ },
47617 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47618 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
47619 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
4638247620 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
46383 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_size), .tmp1x, ._, ._ },
46384 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
46385 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
47621 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
47622 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47623 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4638647624 } },
4638747625 }, .{
47626 .required_cc_abi = .sysv64,
4638847627 .required_features = .{ .sse2, null, null, null },
4638947628 .src_constraints = .{
4639047629 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -46396,7 +47635,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4639647635 },
4639747636 .call_frame = .{ .alignment = .@"16" },
4639847637 .extra_temps = .{
46399 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
47638 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4640047639 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4640147640 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4640247641 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
......@@ -46411,15 +47650,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4641147650 .dst_temps = .{ .mem, .unused },
4641247651 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4641347652 .each = .{ .once = &.{
46414 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ },
46415 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ },
46416 .{ ._, ._dqa, .mov, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._, ._ },
47653 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47654 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
47655 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
4641747656 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
46418 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_size), .tmp1x, ._, ._ },
46419 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
46420 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
47657 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
47658 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47659 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4642147660 } },
4642247661 }, .{
47662 .required_cc_abi = .sysv64,
4642347663 .required_features = .{ .sse, null, null, null },
4642447664 .src_constraints = .{
4642547665 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -46431,7 +47671,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4643147671 },
4643247672 .call_frame = .{ .alignment = .@"16" },
4643347673 .extra_temps = .{
46434 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
47674 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
4643547675 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
4643647676 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
4643747677 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
......@@ -46446,13 +47686,121 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4644647686 .dst_temps = .{ .mem, .unused },
4644747687 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
4644847688 .each = .{ .once = &.{
46449 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ },
46450 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ },
46451 .{ ._, ._ps, .mova, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._, ._ },
47689 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47690 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
47691 .{ ._, ._ps, .mova, .tmp2x, .memi(.src1x, .tmp0), ._, ._ },
4645247692 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
46453 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_size), .tmp1x, ._, ._ },
46454 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
46455 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
47693 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
47694 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47695 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
47696 } },
47697 }, .{
47698 .required_cc_abi = .win64,
47699 .required_features = .{ .avx, null, null, null },
47700 .src_constraints = .{
47701 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47702 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47703 .any,
47704 },
47705 .patterns = &.{
47706 .{ .src = .{ .to_mem, .to_mem, .none } },
47707 },
47708 .call_frame = .{ .alignment = .@"16" },
47709 .extra_temps = .{
47710 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47711 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47712 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47713 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
47714 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47715 .unused,
47716 .unused,
47717 .unused,
47718 .unused,
47719 .unused,
47720 .unused,
47721 },
47722 .dst_temps = .{ .mem, .unused },
47723 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
47724 .each = .{ .once = &.{
47725 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47726 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
47727 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
47728 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
47729 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
47730 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47731 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
47732 } },
47733 }, .{
47734 .required_cc_abi = .win64,
47735 .required_features = .{ .sse2, null, null, null },
47736 .src_constraints = .{
47737 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47738 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47739 .any,
47740 },
47741 .patterns = &.{
47742 .{ .src = .{ .to_mem, .to_mem, .none } },
47743 },
47744 .call_frame = .{ .alignment = .@"16" },
47745 .extra_temps = .{
47746 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47747 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47748 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47749 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
47750 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47751 .unused,
47752 .unused,
47753 .unused,
47754 .unused,
47755 .unused,
47756 .unused,
47757 },
47758 .dst_temps = .{ .mem, .unused },
47759 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
47760 .each = .{ .once = &.{
47761 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47762 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
47763 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
47764 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
47765 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
47766 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47767 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
47768 } },
47769 }, .{
47770 .required_cc_abi = .win64,
47771 .required_features = .{ .sse, null, null, null },
47772 .src_constraints = .{
47773 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47774 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
47775 .any,
47776 },
47777 .patterns = &.{
47778 .{ .src = .{ .to_mem, .to_mem, .none } },
47779 },
47780 .call_frame = .{ .alignment = .@"16" },
47781 .extra_temps = .{
47782 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
47783 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47784 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
47785 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
47786 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
47787 .unused,
47788 .unused,
47789 .unused,
47790 .unused,
47791 .unused,
47792 .unused,
47793 },
47794 .dst_temps = .{ .mem, .unused },
47795 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
47796 .each = .{ .once = &.{
47797 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
47798 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
47799 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
47800 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
47801 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
47802 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
47803 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4645647804 } },
4645747805 } }) catch |err| switch (err) {
4645847806 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
......@@ -50476,6 +51824,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5047651824 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
5047751825 } },
5047851826 }, .{
51827 .required_cc_abi = .sysv64,
5047951828 .required_features = .{ .sse, null, null, null },
5048051829 .src_constraints = .{
5048151830 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -50509,6 +51858,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5050951858 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
5051051859 } },
5051151860 }, .{
51861 .required_cc_abi = .win64,
51862 .required_features = .{ .sse, null, null, null },
51863 .src_constraints = .{
51864 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
51865 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
51866 .any,
51867 },
51868 .patterns = &.{
51869 .{ .src = .{ .to_mem, .to_mem, .none } },
51870 },
51871 .call_frame = .{ .alignment = .@"16" },
51872 .extra_temps = .{
51873 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
51874 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
51875 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
51876 .unused,
51877 .unused,
51878 .unused,
51879 .unused,
51880 .unused,
51881 .unused,
51882 .unused,
51883 .unused,
51884 },
51885 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
51886 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
51887 .each = .{ .once = &.{
51888 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
51889 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
51890 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
51891 } },
51892 }, .{
51893 .required_cc_abi = .sysv64,
5051251894 .required_features = .{ .avx, null, null, null },
5051351895 .src_constraints = .{
5051451896 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -50544,6 +51926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5054451926 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
5054551927 } },
5054651928 }, .{
51929 .required_cc_abi = .sysv64,
5054751930 .required_features = .{ .sse2, null, null, null },
5054851931 .src_constraints = .{
5054951932 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -50579,6 +51962,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5057951962 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
5058051963 } },
5058151964 }, .{
51965 .required_cc_abi = .sysv64,
5058251966 .required_features = .{ .sse, null, null, null },
5058351967 .src_constraints = .{
5058451968 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -50613,6 +51997,114 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5061351997 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
5061451998 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
5061551999 } },
52000 }, .{
52001 .required_cc_abi = .win64,
52002 .required_features = .{ .avx, null, null, null },
52003 .src_constraints = .{
52004 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52005 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52006 .any,
52007 },
52008 .patterns = &.{
52009 .{ .src = .{ .to_mem, .to_mem, .none } },
52010 },
52011 .call_frame = .{ .alignment = .@"16" },
52012 .extra_temps = .{
52013 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52014 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52015 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52016 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
52017 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52018 .unused,
52019 .unused,
52020 .unused,
52021 .unused,
52022 .unused,
52023 .unused,
52024 },
52025 .dst_temps = .{ .mem, .unused },
52026 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
52027 .each = .{ .once = &.{
52028 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
52029 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
52030 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
52031 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
52032 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
52033 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
52034 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
52035 } },
52036 }, .{
52037 .required_cc_abi = .win64,
52038 .required_features = .{ .sse2, null, null, null },
52039 .src_constraints = .{
52040 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52041 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52042 .any,
52043 },
52044 .patterns = &.{
52045 .{ .src = .{ .to_mem, .to_mem, .none } },
52046 },
52047 .call_frame = .{ .alignment = .@"16" },
52048 .extra_temps = .{
52049 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52050 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52051 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52052 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
52053 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52054 .unused,
52055 .unused,
52056 .unused,
52057 .unused,
52058 .unused,
52059 .unused,
52060 },
52061 .dst_temps = .{ .mem, .unused },
52062 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
52063 .each = .{ .once = &.{
52064 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
52065 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
52066 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
52067 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
52068 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
52069 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
52070 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
52071 } },
52072 }, .{
52073 .required_cc_abi = .win64,
52074 .required_features = .{ .sse, null, null, null },
52075 .src_constraints = .{
52076 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52077 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
52078 .any,
52079 },
52080 .patterns = &.{
52081 .{ .src = .{ .to_mem, .to_mem, .none } },
52082 },
52083 .call_frame = .{ .alignment = .@"16" },
52084 .extra_temps = .{
52085 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
52086 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52087 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
52088 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
52089 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
52090 .unused,
52091 .unused,
52092 .unused,
52093 .unused,
52094 .unused,
52095 .unused,
52096 },
52097 .dst_temps = .{ .mem, .unused },
52098 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
52099 .each = .{ .once = &.{
52100 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
52101 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
52102 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
52103 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
52104 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp4x, ._, ._ },
52105 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
52106 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
52107 } },
5061652108 } }) catch |err| switch (err) {
5061752109 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5061852110 @tagName(air_tag),
......@@ -74864,6 +76356,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7486476356 .{ ._, .f_cw, .ld, .tmp0w, ._, ._, ._ },
7486576357 } },
7486676358 }, .{
76359 .required_cc_abi = .sysv64,
7486776360 .required_features = .{ .sse, null, null, null },
7486876361 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7486976362 .patterns = &.{
......@@ -74889,6 +76382,34 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7488976382 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
7489076383 } },
7489176384 }, .{
76385 .required_cc_abi = .win64,
76386 .required_features = .{ .sse, null, null, null },
76387 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
76388 .patterns = &.{
76389 .{ .src = .{ .to_mem, .none, .none } },
76390 },
76391 .call_frame = .{ .alignment = .@"16" },
76392 .extra_temps = .{
76393 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76394 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
76395 .unused,
76396 .unused,
76397 .unused,
76398 .unused,
76399 .unused,
76400 .unused,
76401 .unused,
76402 .unused,
76403 .unused,
76404 },
76405 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
76406 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
76407 .each = .{ .once = &.{
76408 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
76409 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
76410 } },
76411 }, .{
76412 .required_cc_abi = .sysv64,
7489276413 .required_features = .{ .avx, null, null, null },
7489376414 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7489476415 .patterns = &.{
......@@ -74896,7 +76417,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7489676417 },
7489776418 .call_frame = .{ .alignment = .@"16" },
7489876419 .extra_temps = .{
74899 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76420 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7490076421 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7490176422 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
7490276423 .unused,
......@@ -74911,14 +76432,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7491176432 .dst_temps = .{ .mem, .unused },
7491276433 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7491376434 .each = .{ .once = &.{
74914 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
74915 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
76435 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76436 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7491676437 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
74917 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
74918 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
74919 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
76438 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
76439 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76440 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7492076441 } },
7492176442 }, .{
76443 .required_cc_abi = .sysv64,
7492276444 .required_features = .{ .sse2, null, null, null },
7492376445 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7492476446 .patterns = &.{
......@@ -74926,7 +76448,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7492676448 },
7492776449 .call_frame = .{ .alignment = .@"16" },
7492876450 .extra_temps = .{
74929 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76451 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7493076452 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7493176453 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
7493276454 .unused,
......@@ -74941,14 +76463,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7494176463 .dst_temps = .{ .mem, .unused },
7494276464 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7494376465 .each = .{ .once = &.{
74944 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
74945 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
76466 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76467 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7494676468 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
74947 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
74948 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
74949 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
76469 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
76470 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76471 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7495076472 } },
7495176473 }, .{
76474 .required_cc_abi = .sysv64,
7495276475 .required_features = .{ .sse, null, null, null },
7495376476 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7495476477 .patterns = &.{
......@@ -74956,7 +76479,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7495676479 },
7495776480 .call_frame = .{ .alignment = .@"16" },
7495876481 .extra_temps = .{
74959 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
76482 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7496076483 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7496176484 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
7496276485 .unused,
......@@ -74971,12 +76494,105 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7497176494 .dst_temps = .{ .mem, .unused },
7497276495 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7497376496 .each = .{ .once = &.{
74974 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
74975 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
76497 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76498 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7497676499 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
74977 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
74978 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
74979 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
76500 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
76501 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76502 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
76503 } },
76504 }, .{
76505 .required_cc_abi = .win64,
76506 .required_features = .{ .avx, null, null, null },
76507 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
76508 .patterns = &.{
76509 .{ .src = .{ .to_mem, .none, .none } },
76510 },
76511 .call_frame = .{ .alignment = .@"16" },
76512 .extra_temps = .{
76513 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76514 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76515 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
76516 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76517 .unused,
76518 .unused,
76519 .unused,
76520 .unused,
76521 .unused,
76522 .unused,
76523 .unused,
76524 },
76525 .dst_temps = .{ .mem, .unused },
76526 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
76527 .each = .{ .once = &.{
76528 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76529 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
76530 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
76531 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
76532 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76533 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
76534 } },
76535 }, .{
76536 .required_cc_abi = .win64,
76537 .required_features = .{ .sse2, null, null, null },
76538 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
76539 .patterns = &.{
76540 .{ .src = .{ .to_mem, .none, .none } },
76541 },
76542 .call_frame = .{ .alignment = .@"16" },
76543 .extra_temps = .{
76544 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76545 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76546 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
76547 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76548 .unused,
76549 .unused,
76550 .unused,
76551 .unused,
76552 .unused,
76553 .unused,
76554 .unused,
76555 },
76556 .dst_temps = .{ .mem, .unused },
76557 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
76558 .each = .{ .once = &.{
76559 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76560 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
76561 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
76562 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
76563 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76564 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
76565 } },
76566 }, .{
76567 .required_cc_abi = .win64,
76568 .required_features = .{ .sse, null, null, null },
76569 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
76570 .patterns = &.{
76571 .{ .src = .{ .to_mem, .none, .none } },
76572 },
76573 .call_frame = .{ .alignment = .@"16" },
76574 .extra_temps = .{
76575 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
76576 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76577 .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } },
76578 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
76579 .unused,
76580 .unused,
76581 .unused,
76582 .unused,
76583 .unused,
76584 .unused,
76585 .unused,
76586 },
76587 .dst_temps = .{ .mem, .unused },
76588 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
76589 .each = .{ .once = &.{
76590 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
76591 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
76592 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
76593 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
76594 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
76595 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7498076596 } },
7498176597 } }) catch |err| switch (err) {
7498276598 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
......@@ -75589,6 +77205,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7558977205 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7559077206 } },
7559177207 }, .{
77208 .required_cc_abi = .sysv64,
7559277209 .required_features = .{ .sse, null, null, null },
7559377210 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7559477211 .patterns = &.{
......@@ -75614,6 +77231,34 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7561477231 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
7561577232 } },
7561677233 }, .{
77234 .required_cc_abi = .win64,
77235 .required_features = .{ .sse, null, null, null },
77236 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
77237 .patterns = &.{
77238 .{ .src = .{ .to_mem, .none, .none } },
77239 },
77240 .call_frame = .{ .alignment = .@"16" },
77241 .extra_temps = .{
77242 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77243 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
77244 .unused,
77245 .unused,
77246 .unused,
77247 .unused,
77248 .unused,
77249 .unused,
77250 .unused,
77251 .unused,
77252 .unused,
77253 },
77254 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
77255 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
77256 .each = .{ .once = &.{
77257 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
77258 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
77259 } },
77260 }, .{
77261 .required_cc_abi = .sysv64,
7561777262 .required_features = .{ .avx, null, null, null },
7561877263 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7561977264 .patterns = &.{
......@@ -75644,6 +77289,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7564477289 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7564577290 } },
7564677291 }, .{
77292 .required_cc_abi = .sysv64,
7564777293 .required_features = .{ .sse2, null, null, null },
7564877294 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7564977295 .patterns = &.{
......@@ -75674,6 +77320,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7567477320 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7567577321 } },
7567677322 }, .{
77323 .required_cc_abi = .sysv64,
7567777324 .required_features = .{ .sse, null, null, null },
7567877325 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7567977326 .patterns = &.{
......@@ -75703,6 +77350,99 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7570377350 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
7570477351 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7570577352 } },
77353 }, .{
77354 .required_cc_abi = .win64,
77355 .required_features = .{ .avx, null, null, null },
77356 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
77357 .patterns = &.{
77358 .{ .src = .{ .to_mem, .none, .none } },
77359 },
77360 .call_frame = .{ .alignment = .@"16" },
77361 .extra_temps = .{
77362 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77363 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77364 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
77365 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77366 .unused,
77367 .unused,
77368 .unused,
77369 .unused,
77370 .unused,
77371 .unused,
77372 .unused,
77373 },
77374 .dst_temps = .{ .mem, .unused },
77375 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
77376 .each = .{ .once = &.{
77377 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
77378 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
77379 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
77380 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
77381 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
77382 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
77383 } },
77384 }, .{
77385 .required_cc_abi = .win64,
77386 .required_features = .{ .sse2, null, null, null },
77387 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
77388 .patterns = &.{
77389 .{ .src = .{ .to_mem, .none, .none } },
77390 },
77391 .call_frame = .{ .alignment = .@"16" },
77392 .extra_temps = .{
77393 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77394 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77395 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
77396 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77397 .unused,
77398 .unused,
77399 .unused,
77400 .unused,
77401 .unused,
77402 .unused,
77403 .unused,
77404 },
77405 .dst_temps = .{ .mem, .unused },
77406 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
77407 .each = .{ .once = &.{
77408 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
77409 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
77410 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
77411 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
77412 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
77413 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
77414 } },
77415 }, .{
77416 .required_cc_abi = .win64,
77417 .required_features = .{ .sse, null, null, null },
77418 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
77419 .patterns = &.{
77420 .{ .src = .{ .to_mem, .none, .none } },
77421 },
77422 .call_frame = .{ .alignment = .@"16" },
77423 .extra_temps = .{
77424 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
77425 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77426 .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } },
77427 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
77428 .unused,
77429 .unused,
77430 .unused,
77431 .unused,
77432 .unused,
77433 .unused,
77434 .unused,
77435 },
77436 .dst_temps = .{ .mem, .unused },
77437 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
77438 .each = .{ .once = &.{
77439 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
77440 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
77441 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
77442 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
77443 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
77444 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
77445 } },
7570677446 } },
7570777447 }) catch |err| switch (err) {
7570877448 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
......@@ -78312,6 +80052,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7831280052 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7831380053 } },
7831480054 }, .{
80055 .required_cc_abi = .sysv64,
7831580056 .required_features = .{ .sse, null, null, null },
7831680057 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7831780058 .patterns = &.{
......@@ -78342,6 +80083,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7834280083 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
7834380084 } },
7834480085 }, .{
80086 .required_cc_abi = .win64,
80087 .required_features = .{ .sse, null, null, null },
80088 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
80089 .patterns = &.{
80090 .{ .src = .{ .to_mem, .none, .none } },
80091 },
80092 .call_frame = .{ .alignment = .@"16" },
80093 .extra_temps = .{
80094 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80095 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80096 else => unreachable,
80097 .down => "floorq",
80098 .up => "ceilq",
80099 .zero => "truncq",
80100 } } },
80101 .unused,
80102 .unused,
80103 .unused,
80104 .unused,
80105 .unused,
80106 .unused,
80107 .unused,
80108 .unused,
80109 .unused,
80110 },
80111 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
80112 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
80113 .each = .{ .once = &.{
80114 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
80115 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
80116 } },
80117 }, .{
80118 .required_cc_abi = .sysv64,
7834580119 .required_features = .{ .avx, null, null, null },
7834680120 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7834780121 .patterns = &.{
......@@ -78349,7 +80123,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7834980123 },
7835080124 .call_frame = .{ .alignment = .@"16" },
7835180125 .extra_temps = .{
78352 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
80126 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7835380127 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7835480128 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
7835580129 else => unreachable,
......@@ -78369,14 +80143,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7836980143 .dst_temps = .{ .mem, .unused },
7837080144 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7837180145 .each = .{ .once = &.{
78372 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
78373 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
80146 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80147 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7837480148 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
78375 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
78376 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
78377 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
80149 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
80150 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80151 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7837880152 } },
7837980153 }, .{
80154 .required_cc_abi = .sysv64,
7838080155 .required_features = .{ .sse2, null, null, null },
7838180156 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7838280157 .patterns = &.{
......@@ -78384,7 +80159,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7838480159 },
7838580160 .call_frame = .{ .alignment = .@"16" },
7838680161 .extra_temps = .{
78387 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
80162 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7838880163 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7838980164 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
7839080165 else => unreachable,
......@@ -78404,14 +80179,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7840480179 .dst_temps = .{ .mem, .unused },
7840580180 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7840680181 .each = .{ .once = &.{
78407 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
78408 .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
80182 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80183 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7840980184 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
78410 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
78411 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
78412 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
80185 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
80186 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80187 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7841380188 } },
7841480189 }, .{
80190 .required_cc_abi = .sysv64,
7841580191 .required_features = .{ .sse, null, null, null },
7841680192 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
7841780193 .patterns = &.{
......@@ -78419,7 +80195,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7841980195 },
7842080196 .call_frame = .{ .alignment = .@"16" },
7842180197 .extra_temps = .{
78422 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
80198 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
7842380199 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7842480200 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
7842580201 else => unreachable,
......@@ -78439,12 +80215,120 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7843980215 .dst_temps = .{ .mem, .unused },
7844080216 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
7844180217 .each = .{ .once = &.{
78442 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
78443 .{ .@"0:", ._ps, .mova, .tmp1x, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
80218 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80219 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
7844480220 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
78445 .{ ._, ._ps, .mova, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
78446 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
78447 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
80221 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
80222 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80223 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
80224 } },
80225 }, .{
80226 .required_cc_abi = .win64,
80227 .required_features = .{ .avx, null, null, null },
80228 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
80229 .patterns = &.{
80230 .{ .src = .{ .to_mem, .none, .none } },
80231 },
80232 .call_frame = .{ .alignment = .@"16" },
80233 .extra_temps = .{
80234 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80235 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80236 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80237 else => unreachable,
80238 .down => "floorq",
80239 .up => "ceilq",
80240 .zero => "truncq",
80241 } } },
80242 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80243 .unused,
80244 .unused,
80245 .unused,
80246 .unused,
80247 .unused,
80248 .unused,
80249 .unused,
80250 },
80251 .dst_temps = .{ .mem, .unused },
80252 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
80253 .each = .{ .once = &.{
80254 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80255 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
80256 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
80257 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
80258 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80259 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
80260 } },
80261 }, .{
80262 .required_cc_abi = .win64,
80263 .required_features = .{ .sse2, null, null, null },
80264 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
80265 .patterns = &.{
80266 .{ .src = .{ .to_mem, .none, .none } },
80267 },
80268 .call_frame = .{ .alignment = .@"16" },
80269 .extra_temps = .{
80270 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80271 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80272 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80273 else => unreachable,
80274 .down => "floorq",
80275 .up => "ceilq",
80276 .zero => "truncq",
80277 } } },
80278 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80279 .unused,
80280 .unused,
80281 .unused,
80282 .unused,
80283 .unused,
80284 .unused,
80285 .unused,
80286 },
80287 .dst_temps = .{ .mem, .unused },
80288 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
80289 .each = .{ .once = &.{
80290 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80291 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
80292 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
80293 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
80294 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80295 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
80296 } },
80297 }, .{
80298 .required_cc_abi = .win64,
80299 .required_features = .{ .sse, null, null, null },
80300 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
80301 .patterns = &.{
80302 .{ .src = .{ .to_mem, .none, .none } },
80303 },
80304 .call_frame = .{ .alignment = .@"16" },
80305 .extra_temps = .{
80306 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
80307 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80308 .{ .type = .usize, .kind = .{ .extern_func = switch (direction) {
80309 else => unreachable,
80310 .down => "floorq",
80311 .up => "ceilq",
80312 .zero => "truncq",
80313 } } },
80314 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
80315 .unused,
80316 .unused,
80317 .unused,
80318 .unused,
80319 .unused,
80320 .unused,
80321 .unused,
80322 },
80323 .dst_temps = .{ .mem, .unused },
80324 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
80325 .each = .{ .once = &.{
80326 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
80327 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
80328 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
80329 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
80330 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
80331 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7844880332 } },
7844980333 } },
7845080334 }) catch |err| switch (err) {
......@@ -79063,7 +80947,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7906380947 .call_frame = .{ .alignment = .@"16" },
7906480948 .extra_temps = .{
7906580949 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79066 .{ .type = .i32, .kind = .{ .reg = .eax } },
80950 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7906780951 .unused,
7906880952 .unused,
7906980953 .unused,
......@@ -79398,6 +81282,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7939881282 },
7939981283 } },
7940081284 }, .{
81285 .required_cc_abi = .sysv64,
7940181286 .required_features = .{ .sse, null, null, null },
7940281287 .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword }, .any },
7940381288 .patterns = &.{
......@@ -79410,7 +81295,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7941081295 .call_frame = .{ .alignment = .@"16" },
7941181296 .extra_temps = .{
7941281297 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
79413 .{ .type = .i32, .kind = .{ .reg = .eax } },
81298 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7941481299 .unused,
7941581300 .unused,
7941681301 .unused,
......@@ -79430,6 +81315,38 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7943081315 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
7943181316 .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ },
7943281317 } },
81318 }, .{
81319 .required_cc_abi = .win64,
81320 .required_features = .{ .sse, null, null, null },
81321 .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword }, .any },
81322 .patterns = &.{
81323 .{ .src = .{ .to_mem, .to_mem, .none } },
81324 },
81325 .call_frame = .{ .alignment = .@"16" },
81326 .extra_temps = .{
81327 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
81328 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
81329 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
81330 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
81331 .unused,
81332 .unused,
81333 .unused,
81334 .unused,
81335 .unused,
81336 .unused,
81337 .unused,
81338 },
81339 .dst_temps = .{ .{ .cc = switch (strict) {
81340 true => .l,
81341 false => .le,
81342 } }, .unused },
81343 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
81344 .each = .{ .once = &.{
81345 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
81346 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
81347 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
81348 .{ ._, ._, .@"test", .tmp3d, .tmp3d, ._, ._ },
81349 } },
7943381350 } },
7943481351 });
7943581352 } else err: {
......@@ -79575,7 +81492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7957581492 .call_frame = .{ .alignment = .@"16" },
7957681493 .extra_temps = .{
7957781494 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
79578 .{ .type = .i32, .kind = .{ .reg = .eax } },
81495 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7957981496 .unused,
7958081497 .unused,
7958181498 .unused,
......@@ -79934,6 +81851,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7993481851 },
7993581852 } },
7993681853 }, .{
81854 .required_cc_abi = .sysv64,
7993781855 .required_features = .{ .sse, null, null, null },
7993881856 .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword }, .any },
7993981857 .patterns = &.{
......@@ -79946,7 +81864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7994681864 .call_frame = .{ .alignment = .@"16" },
7994781865 .extra_temps = .{
7994881866 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
79949 .{ .type = .i32, .kind = .{ .reg = .eax } },
81867 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
7995081868 .unused,
7995181869 .unused,
7995281870 .unused,
......@@ -79963,6 +81881,35 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7996381881 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
7996481882 .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ },
7996581883 } },
81884 }, .{
81885 .required_cc_abi = .win64,
81886 .required_features = .{ .sse, null, null, null },
81887 .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword }, .any },
81888 .patterns = &.{
81889 .{ .src = .{ .to_mem, .to_mem, .none } },
81890 },
81891 .call_frame = .{ .alignment = .@"16" },
81892 .extra_temps = .{
81893 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
81894 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
81895 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
81896 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
81897 .unused,
81898 .unused,
81899 .unused,
81900 .unused,
81901 .unused,
81902 .unused,
81903 .unused,
81904 },
81905 .dst_temps = .{ .{ .cc = .z }, .unused },
81906 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
81907 .each = .{ .once = &.{
81908 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
81909 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
81910 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
81911 .{ ._, ._, .@"test", .tmp3d, .tmp3d, ._, ._ },
81912 } },
7996681913 } },
7996781914 }) catch |err| break :err err;
7996881915 switch (cmp_op) {
......@@ -80018,14 +81965,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8001881965 }
8001981966 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
8002081967 },
80021 .cmp_vector, .cmp_vector_optimized => |air_tag| fallback: {
81968 .cmp_vector, .cmp_vector_optimized => |air_tag| {
8002281969 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
8002381970 const vector_cmp = cg.air.extraData(Air.VectorCmp, ty_pl.payload).data;
80024 switch (vector_cmp.compareOperator()) {
80025 .eq, .neq => {},
80026 .lt, .lte, .gte, .gt => if (cg.floatBits(cg.typeOf(vector_cmp.lhs).childType(zcu)) == null)
80027 break :fallback try cg.airCmpVector(inst),
80028 }
8002981971 var ops = try cg.tempsFromOperands(inst, .{ vector_cmp.lhs, vector_cmp.rhs });
8003081972 var res: [1]Temp = undefined;
8003181973 (err: switch (vector_cmp.compareOperator()) {
......@@ -80615,7 +82557,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8061582557 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8061682558 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8061782559 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80618 .{ .type = .i32, .kind = .{ .reg = .eax } },
82560 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8061982561 .{ .type = .u8, .kind = .{ .reg = .cl } },
8062082562 .{ .type = .u32, .kind = .{ .reg = .edx } },
8062182563 .unused,
......@@ -80659,7 +82601,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8065982601 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8066082602 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8066182603 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80662 .{ .type = .i32, .kind = .{ .reg = .eax } },
82604 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8066382605 .{ .type = .u8, .kind = .{ .reg = .cl } },
8066482606 .{ .type = .u32, .kind = .{ .reg = .edx } },
8066582607 .unused,
......@@ -80703,7 +82645,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8070382645 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8070482646 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8070582647 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80706 .{ .type = .i32, .kind = .{ .reg = .eax } },
82648 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8070782649 .{ .type = .u8, .kind = .{ .reg = .cl } },
8070882650 .{ .type = .u32, .kind = .{ .reg = .edx } },
8070982651 .unused,
......@@ -80748,7 +82690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8074882690 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8074982691 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8075082692 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80751 .{ .type = .i32, .kind = .{ .reg = .eax } },
82693 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8075282694 .{ .type = .u8, .kind = .{ .reg = .cl } },
8075382695 .{ .type = .u32, .kind = .{ .reg = .edx } },
8075482696 .unused,
......@@ -80793,7 +82735,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8079382735 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8079482736 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8079582737 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80796 .{ .type = .i32, .kind = .{ .reg = .eax } },
82738 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8079782739 .{ .type = .u8, .kind = .{ .reg = .cl } },
8079882740 .{ .type = .u32, .kind = .{ .reg = .edx } },
8079982741 .{ .type = .f32, .kind = .mem },
......@@ -80840,7 +82782,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8084082782 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8084182783 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8084282784 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80843 .{ .type = .i32, .kind = .{ .reg = .eax } },
82785 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8084482786 .{ .type = .u8, .kind = .{ .reg = .cl } },
8084582787 .{ .type = .u32, .kind = .{ .reg = .edx } },
8084682788 .{ .type = .f32, .kind = .mem },
......@@ -80887,7 +82829,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8088782829 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8088882830 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8088982831 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80890 .{ .type = .i32, .kind = .{ .reg = .eax } },
82832 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8089182833 .{ .type = .u8, .kind = .{ .reg = .cl } },
8089282834 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8089382835 .unused,
......@@ -80940,7 +82882,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8094082882 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8094182883 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8094282884 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80943 .{ .type = .i32, .kind = .{ .reg = .eax } },
82885 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8094482886 .{ .type = .u8, .kind = .{ .reg = .cl } },
8094582887 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8094682888 .unused,
......@@ -80993,7 +82935,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8099382935 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8099482936 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8099582937 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
80996 .{ .type = .i32, .kind = .{ .reg = .eax } },
82938 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8099782939 .{ .type = .u8, .kind = .{ .reg = .cl } },
8099882940 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8099982941 .unused,
......@@ -81047,7 +82989,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8104782989 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8104882990 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8104982991 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
81050 .{ .type = .i32, .kind = .{ .reg = .eax } },
82992 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8105182993 .{ .type = .u8, .kind = .{ .reg = .cl } },
8105282994 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8105382995 .unused,
......@@ -81101,7 +83043,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8110183043 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8110283044 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8110383045 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
81104 .{ .type = .i32, .kind = .{ .reg = .eax } },
83046 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8110583047 .{ .type = .u8, .kind = .{ .reg = .cl } },
8110683048 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8110783049 .{ .type = .f32, .kind = .mem },
......@@ -81157,7 +83099,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8115783099 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8115883100 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8115983101 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
81160 .{ .type = .i32, .kind = .{ .reg = .eax } },
83102 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8116183103 .{ .type = .u8, .kind = .{ .reg = .cl } },
8116283104 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8116383105 .{ .type = .f32, .kind = .mem },
......@@ -81984,7 +83926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8198483926 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8198583927 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8198683928 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
81987 .{ .type = .i32, .kind = .{ .reg = .eax } },
83929 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8198883930 .{ .type = .u8, .kind = .{ .reg = .cl } },
8198983931 .{ .type = .u32, .kind = .{ .reg = .edx } },
8199083932 .unused,
......@@ -82028,7 +83970,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8202883970 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8202983971 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8203083972 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82031 .{ .type = .i32, .kind = .{ .reg = .eax } },
83973 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8203283974 .{ .type = .u8, .kind = .{ .reg = .cl } },
8203383975 .{ .type = .u32, .kind = .{ .reg = .edx } },
8203483976 .unused,
......@@ -82072,7 +84014,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8207284014 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8207384015 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8207484016 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82075 .{ .type = .i32, .kind = .{ .reg = .eax } },
84017 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8207684018 .{ .type = .u8, .kind = .{ .reg = .cl } },
8207784019 .{ .type = .u32, .kind = .{ .reg = .edx } },
8207884020 .unused,
......@@ -82116,7 +84058,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8211684058 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8211784059 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8211884060 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82119 .{ .type = .i32, .kind = .{ .reg = .eax } },
84061 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8212084062 .{ .type = .u8, .kind = .{ .reg = .cl } },
8212184063 .{ .type = .u32, .kind = .{ .reg = .edx } },
8212284064 .unused,
......@@ -82160,7 +84102,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8216084102 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8216184103 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8216284104 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82163 .{ .type = .i32, .kind = .{ .reg = .eax } },
84105 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8216484106 .{ .type = .u8, .kind = .{ .reg = .cl } },
8216584107 .{ .type = .u32, .kind = .{ .reg = .edx } },
8216684108 .unused,
......@@ -82204,7 +84146,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8220484146 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8220584147 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8220684148 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82207 .{ .type = .i32, .kind = .{ .reg = .eax } },
84149 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8220884150 .{ .type = .u8, .kind = .{ .reg = .cl } },
8220984151 .{ .type = .u32, .kind = .{ .reg = .edx } },
8221084152 .unused,
......@@ -82248,7 +84190,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8224884190 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8224984191 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8225084192 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82251 .{ .type = .i32, .kind = .{ .reg = .eax } },
84193 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8225284194 .{ .type = .u8, .kind = .{ .reg = .cl } },
8225384195 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8225484196 .unused,
......@@ -82301,7 +84243,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8230184243 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8230284244 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8230384245 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82304 .{ .type = .i32, .kind = .{ .reg = .eax } },
84246 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8230584247 .{ .type = .u8, .kind = .{ .reg = .cl } },
8230684248 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8230784249 .unused,
......@@ -82354,7 +84296,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8235484296 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8235584297 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8235684298 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82357 .{ .type = .i32, .kind = .{ .reg = .eax } },
84299 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8235884300 .{ .type = .u8, .kind = .{ .reg = .cl } },
8235984301 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8236084302 .unused,
......@@ -82407,7 +84349,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8240784349 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8240884350 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8240984351 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82410 .{ .type = .i32, .kind = .{ .reg = .eax } },
84352 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8241184353 .{ .type = .u8, .kind = .{ .reg = .cl } },
8241284354 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8241384355 .unused,
......@@ -82460,7 +84402,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8246084402 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8246184403 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8246284404 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82463 .{ .type = .i32, .kind = .{ .reg = .eax } },
84405 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8246484406 .{ .type = .u8, .kind = .{ .reg = .cl } },
8246584407 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8246684408 .unused,
......@@ -82513,7 +84455,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8251384455 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8251484456 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8251584457 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
82516 .{ .type = .i32, .kind = .{ .reg = .eax } },
84458 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8251784459 .{ .type = .u8, .kind = .{ .reg = .cl } },
8251884460 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8251984461 .unused,
......@@ -85125,7 +87067,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8512587067 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8512687068 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8512787069 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85128 .{ .type = .i32, .kind = .{ .reg = .eax } },
87070 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8512987071 .{ .type = .u8, .kind = .{ .reg = .cl } },
8513087072 .{ .type = .u32, .kind = .{ .reg = .edx } },
8513187073 .unused,
......@@ -85169,7 +87111,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8516987111 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8517087112 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8517187113 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85172 .{ .type = .i32, .kind = .{ .reg = .eax } },
87114 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8517387115 .{ .type = .u8, .kind = .{ .reg = .cl } },
8517487116 .{ .type = .u32, .kind = .{ .reg = .edx } },
8517587117 .unused,
......@@ -85213,7 +87155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8521387155 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8521487156 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8521587157 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85216 .{ .type = .i32, .kind = .{ .reg = .eax } },
87158 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8521787159 .{ .type = .u8, .kind = .{ .reg = .cl } },
8521887160 .{ .type = .u32, .kind = .{ .reg = .edx } },
8521987161 .unused,
......@@ -85258,7 +87200,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8525887200 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8525987201 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8526087202 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85261 .{ .type = .i32, .kind = .{ .reg = .eax } },
87203 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8526287204 .{ .type = .u8, .kind = .{ .reg = .cl } },
8526387205 .{ .type = .u32, .kind = .{ .reg = .edx } },
8526487206 .unused,
......@@ -85303,7 +87245,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8530387245 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8530487246 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8530587247 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85306 .{ .type = .i32, .kind = .{ .reg = .eax } },
87248 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8530787249 .{ .type = .u8, .kind = .{ .reg = .cl } },
8530887250 .{ .type = .u32, .kind = .{ .reg = .edx } },
8530987251 .{ .type = .f32, .kind = .mem },
......@@ -85350,7 +87292,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8535087292 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8535187293 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8535287294 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85353 .{ .type = .i32, .kind = .{ .reg = .eax } },
87295 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8535487296 .{ .type = .u8, .kind = .{ .reg = .cl } },
8535587297 .{ .type = .u32, .kind = .{ .reg = .edx } },
8535687298 .{ .type = .f32, .kind = .mem },
......@@ -85397,7 +87339,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8539787339 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8539887340 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8539987341 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85400 .{ .type = .i32, .kind = .{ .reg = .eax } },
87342 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8540187343 .{ .type = .u8, .kind = .{ .reg = .cl } },
8540287344 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8540387345 .unused,
......@@ -85450,7 +87392,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8545087392 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8545187393 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8545287394 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85453 .{ .type = .i32, .kind = .{ .reg = .eax } },
87395 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8545487396 .{ .type = .u8, .kind = .{ .reg = .cl } },
8545587397 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8545687398 .unused,
......@@ -85503,7 +87445,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8550387445 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8550487446 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8550587447 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85506 .{ .type = .i32, .kind = .{ .reg = .eax } },
87448 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8550787449 .{ .type = .u8, .kind = .{ .reg = .cl } },
8550887450 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8550987451 .unused,
......@@ -85557,7 +87499,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8555787499 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8555887500 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8555987501 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85560 .{ .type = .i32, .kind = .{ .reg = .eax } },
87502 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8556187503 .{ .type = .u8, .kind = .{ .reg = .cl } },
8556287504 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8556387505 .unused,
......@@ -85611,7 +87553,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8561187553 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8561287554 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8561387555 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85614 .{ .type = .i32, .kind = .{ .reg = .eax } },
87556 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8561587557 .{ .type = .u8, .kind = .{ .reg = .cl } },
8561687558 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8561787559 .{ .type = .f32, .kind = .mem },
......@@ -85667,7 +87609,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8566787609 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8566887610 .{ .type = .f16, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8566987611 .{ .type = .usize, .kind = .{ .extern_func = "__cmphf2" } },
85670 .{ .type = .i32, .kind = .{ .reg = .eax } },
87612 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8567187613 .{ .type = .u8, .kind = .{ .reg = .cl } },
8567287614 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8567387615 .{ .type = .f32, .kind = .mem },
......@@ -86508,7 +88450,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8650888450 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8650988451 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8651088452 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86511 .{ .type = .i32, .kind = .{ .reg = .eax } },
88453 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8651288454 .{ .type = .u8, .kind = .{ .reg = .cl } },
8651388455 .{ .type = .u32, .kind = .{ .reg = .edx } },
8651488456 .unused,
......@@ -86552,7 +88494,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8655288494 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8655388495 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8655488496 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86555 .{ .type = .i32, .kind = .{ .reg = .eax } },
88497 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8655688498 .{ .type = .u8, .kind = .{ .reg = .cl } },
8655788499 .{ .type = .u32, .kind = .{ .reg = .edx } },
8655888500 .unused,
......@@ -86596,7 +88538,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8659688538 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8659788539 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8659888540 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86599 .{ .type = .i32, .kind = .{ .reg = .eax } },
88541 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8660088542 .{ .type = .u8, .kind = .{ .reg = .cl } },
8660188543 .{ .type = .u32, .kind = .{ .reg = .edx } },
8660288544 .unused,
......@@ -86640,7 +88582,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8664088582 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8664188583 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8664288584 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86643 .{ .type = .i32, .kind = .{ .reg = .eax } },
88585 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8664488586 .{ .type = .u8, .kind = .{ .reg = .cl } },
8664588587 .{ .type = .u32, .kind = .{ .reg = .edx } },
8664688588 .unused,
......@@ -86684,7 +88626,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8668488626 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8668588627 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8668688628 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86687 .{ .type = .i32, .kind = .{ .reg = .eax } },
88629 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8668888630 .{ .type = .u8, .kind = .{ .reg = .cl } },
8668988631 .{ .type = .u32, .kind = .{ .reg = .edx } },
8669088632 .unused,
......@@ -86728,7 +88670,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8672888670 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8672988671 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8673088672 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86731 .{ .type = .i32, .kind = .{ .reg = .eax } },
88673 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8673288674 .{ .type = .u8, .kind = .{ .reg = .cl } },
8673388675 .{ .type = .u32, .kind = .{ .reg = .edx } },
8673488676 .unused,
......@@ -86772,7 +88714,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8677288714 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8677388715 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8677488716 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86775 .{ .type = .i32, .kind = .{ .reg = .eax } },
88717 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8677688718 .{ .type = .u8, .kind = .{ .reg = .cl } },
8677788719 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8677888720 .unused,
......@@ -86825,7 +88767,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8682588767 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8682688768 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8682788769 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86828 .{ .type = .i32, .kind = .{ .reg = .eax } },
88770 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8682988771 .{ .type = .u8, .kind = .{ .reg = .cl } },
8683088772 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8683188773 .unused,
......@@ -86878,7 +88820,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8687888820 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8687988821 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8688088822 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86881 .{ .type = .i32, .kind = .{ .reg = .eax } },
88823 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8688288824 .{ .type = .u8, .kind = .{ .reg = .cl } },
8688388825 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8688488826 .unused,
......@@ -86931,7 +88873,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8693188873 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8693288874 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8693388875 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86934 .{ .type = .i32, .kind = .{ .reg = .eax } },
88876 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8693588877 .{ .type = .u8, .kind = .{ .reg = .cl } },
8693688878 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8693788879 .unused,
......@@ -86984,7 +88926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8698488926 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8698588927 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8698688928 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
86987 .{ .type = .i32, .kind = .{ .reg = .eax } },
88929 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8698888930 .{ .type = .u8, .kind = .{ .reg = .cl } },
8698988931 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8699088932 .unused,
......@@ -87037,7 +88979,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8703788979 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8703888980 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8703988981 .{ .type = .usize, .kind = .{ .extern_func = "__cmptf2" } },
87040 .{ .type = .i32, .kind = .{ .reg = .eax } },
88982 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8704188983 .{ .type = .u8, .kind = .{ .reg = .cl } },
8704288984 .{ .type = .u64, .kind = .{ .reg = .rdx } },
8704388985 .unused,
......@@ -88690,6 +90632,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8869090632 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8869190633 } },
8869290634 }, .{
90635 .required_cc_abi = .sysv64,
8869390636 .required_features = .{ .sse, null, null, null },
8869490637 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8869590638 .dst_constraints = .{ .{ .scalar_float = .{ .of = .word, .is = .word } }, .any },
......@@ -88716,6 +90659,35 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8871690659 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
8871790660 } },
8871890661 }, .{
90662 .required_cc_abi = .win64,
90663 .required_features = .{ .sse, null, null, null },
90664 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90665 .dst_constraints = .{ .{ .scalar_float = .{ .of = .word, .is = .word } }, .any },
90666 .patterns = &.{
90667 .{ .src = .{ .to_mem, .none, .none } },
90668 },
90669 .call_frame = .{ .alignment = .@"16" },
90670 .extra_temps = .{
90671 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90672 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
90673 .unused,
90674 .unused,
90675 .unused,
90676 .unused,
90677 .unused,
90678 .unused,
90679 .unused,
90680 .unused,
90681 .unused,
90682 },
90683 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
90684 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
90685 .each = .{ .once = &.{
90686 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
90687 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
90688 } },
90689 }, .{
90690 .required_cc_abi = .sysv64,
8871990691 .required_features = .{ .avx, null, null, null },
8872090692 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8872190693 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
......@@ -88747,6 +90719,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8874790719 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8874890720 } },
8874990721 }, .{
90722 .required_cc_abi = .sysv64,
8875090723 .required_features = .{ .sse4_1, null, null, null },
8875190724 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8875290725 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
......@@ -88778,6 +90751,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8877890751 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8877990752 } },
8878090753 }, .{
90754 .required_cc_abi = .sysv64,
8878190755 .required_features = .{ .sse2, null, null, null },
8878290756 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8878390757 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
......@@ -88810,6 +90784,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8881090784 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8881190785 } },
8881290786 }, .{
90787 .required_cc_abi = .sysv64,
8881390788 .required_features = .{ .sse, null, null, null },
8881490789 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8881590790 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
......@@ -88819,7 +90794,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8881990794 .call_frame = .{ .alignment = .@"16" },
8882090795 .extra_temps = .{
8882190796 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
88822 .{ .type = .f64, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90797 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8882390798 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
8882490799 .{ .type = .f32, .kind = .mem },
8882590800 .{ .type = .f16, .kind = .{ .reg = .ax } },
......@@ -88843,6 +90818,138 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8884390818 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8884490819 } },
8884590820 }, .{
90821 .required_cc_abi = .win64,
90822 .required_features = .{ .avx, null, null, null },
90823 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90824 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
90825 .patterns = &.{
90826 .{ .src = .{ .to_mem, .none, .none } },
90827 },
90828 .call_frame = .{ .alignment = .@"16" },
90829 .extra_temps = .{
90830 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
90831 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90832 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
90833 .{ .type = .f16, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90834 .unused,
90835 .unused,
90836 .unused,
90837 .unused,
90838 .unused,
90839 .unused,
90840 .unused,
90841 },
90842 .dst_temps = .{ .mem, .unused },
90843 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
90844 .each = .{ .once = &.{
90845 .{ ._, ._, .mov, .tmp0d, .sia(-2, .dst0, .add_unaligned_size), ._, ._ },
90846 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"8", .tmp0), ._, ._ },
90847 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
90848 .{ ._, .vp_w, .extr, .memi(.dst0w, .tmp0), .tmp3x, .ui(0), ._ },
90849 .{ ._, ._, .sub, .tmp0d, .si(2), ._, ._ },
90850 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
90851 } },
90852 }, .{
90853 .required_cc_abi = .win64,
90854 .required_features = .{ .sse4_1, null, null, null },
90855 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90856 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
90857 .patterns = &.{
90858 .{ .src = .{ .to_mem, .none, .none } },
90859 },
90860 .call_frame = .{ .alignment = .@"16" },
90861 .extra_temps = .{
90862 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
90863 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90864 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
90865 .{ .type = .f16, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90866 .unused,
90867 .unused,
90868 .unused,
90869 .unused,
90870 .unused,
90871 .unused,
90872 .unused,
90873 },
90874 .dst_temps = .{ .mem, .unused },
90875 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
90876 .each = .{ .once = &.{
90877 .{ ._, ._, .mov, .tmp0d, .sia(-2, .dst0, .add_unaligned_size), ._, ._ },
90878 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"8", .tmp0), ._, ._ },
90879 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
90880 .{ ._, .p_w, .extr, .memi(.dst0w, .tmp0), .tmp3x, .ui(0), ._ },
90881 .{ ._, ._, .sub, .tmp0d, .si(2), ._, ._ },
90882 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
90883 } },
90884 }, .{
90885 .required_cc_abi = .win64,
90886 .required_features = .{ .sse2, null, null, null },
90887 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90888 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
90889 .patterns = &.{
90890 .{ .src = .{ .to_mem, .none, .none } },
90891 },
90892 .call_frame = .{ .alignment = .@"16" },
90893 .extra_temps = .{
90894 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
90895 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90896 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
90897 .{ .type = .f16, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90898 .{ .type = .f16, .kind = .{ .reg = .ax } },
90899 .unused,
90900 .unused,
90901 .unused,
90902 .unused,
90903 .unused,
90904 .unused,
90905 },
90906 .dst_temps = .{ .mem, .unused },
90907 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
90908 .each = .{ .once = &.{
90909 .{ ._, ._, .mov, .tmp0d, .sia(-2, .dst0, .add_unaligned_size), ._, ._ },
90910 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"8", .tmp0), ._, ._ },
90911 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
90912 .{ ._, .p_w, .extr, .tmp4d, .tmp3x, .ui(0), ._ },
90913 .{ ._, ._, .mov, .memi(.dst0w, .tmp0), .tmp4w, ._, ._ },
90914 .{ ._, ._, .sub, .tmp0d, .si(2), ._, ._ },
90915 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
90916 } },
90917 }, .{
90918 .required_cc_abi = .win64,
90919 .required_features = .{ .sse, null, null, null },
90920 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90921 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .word, .is = .word } }, .any },
90922 .patterns = &.{
90923 .{ .src = .{ .to_mem, .none, .none } },
90924 },
90925 .call_frame = .{ .alignment = .@"16" },
90926 .extra_temps = .{
90927 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
90928 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90929 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfhf2" } },
90930 .{ .type = .f32, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90931 .{ .type = .f32, .kind = .mem },
90932 .{ .type = .f16, .kind = .{ .reg = .ax } },
90933 .unused,
90934 .unused,
90935 .unused,
90936 .unused,
90937 .unused,
90938 },
90939 .dst_temps = .{ .mem, .unused },
90940 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
90941 .each = .{ .once = &.{
90942 .{ ._, ._, .mov, .tmp0d, .sia(-2, .dst0, .add_unaligned_size), ._, ._ },
90943 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"8", .tmp0), ._, ._ },
90944 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
90945 .{ ._, ._ss, .mov, .mem(.tmp4d), .tmp3x, ._, ._ },
90946 .{ ._, ._, .mov, .tmp5d, .mem(.tmp4d), ._, ._ },
90947 .{ ._, ._, .mov, .memi(.dst0w, .tmp0), .tmp5w, ._, ._ },
90948 .{ ._, ._, .sub, .tmp0d, .si(2), ._, ._ },
90949 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
90950 } },
90951 }, .{
90952 .required_cc_abi = .sysv64,
8884690953 .required_features = .{ .sse, null, null, null },
8884790954 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8884890955 .dst_constraints = .{ .{ .scalar_float = .{ .of = .dword, .is = .dword } }, .any },
......@@ -88869,6 +90976,35 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8886990976 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
8887090977 } },
8887190978 }, .{
90979 .required_cc_abi = .win64,
90980 .required_features = .{ .sse, null, null, null },
90981 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
90982 .dst_constraints = .{ .{ .scalar_float = .{ .of = .dword, .is = .dword } }, .any },
90983 .patterns = &.{
90984 .{ .src = .{ .to_mem, .none, .none } },
90985 },
90986 .call_frame = .{ .alignment = .@"16" },
90987 .extra_temps = .{
90988 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
90989 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
90990 .unused,
90991 .unused,
90992 .unused,
90993 .unused,
90994 .unused,
90995 .unused,
90996 .unused,
90997 .unused,
90998 .unused,
90999 },
91000 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
91001 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
91002 .each = .{ .once = &.{
91003 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
91004 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
91005 } },
91006 }, .{
91007 .required_cc_abi = .sysv64,
8887291008 .required_features = .{ .avx, null, null, null },
8887391009 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8887491010 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .dword, .is = .dword } }, .any },
......@@ -88900,6 +91036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8890091036 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8890191037 } },
8890291038 }, .{
91039 .required_cc_abi = .sysv64,
8890391040 .required_features = .{ .sse2, null, null, null },
8890491041 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8890591042 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .dword, .is = .dword } }, .any },
......@@ -88931,6 +91068,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8893191068 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8893291069 } },
8893391070 }, .{
91071 .required_cc_abi = .sysv64,
8893491072 .required_features = .{ .sse, null, null, null },
8893591073 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8893691074 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .dword, .is = .dword } }, .any },
......@@ -88962,6 +91100,71 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8896291100 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8896391101 } },
8896491102 }, .{
91103 .required_cc_abi = .win64,
91104 .required_features = .{ .avx, null, null, null },
91105 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91106 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .dword, .is = .dword } }, .any },
91107 .patterns = &.{
91108 .{ .src = .{ .to_mem, .none, .none } },
91109 },
91110 .call_frame = .{ .alignment = .@"16" },
91111 .extra_temps = .{
91112 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
91113 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91114 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
91115 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91116 .unused,
91117 .unused,
91118 .unused,
91119 .unused,
91120 .unused,
91121 .unused,
91122 .unused,
91123 },
91124 .dst_temps = .{ .mem, .unused },
91125 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
91126 .each = .{ .once = &.{
91127 .{ ._, ._, .mov, .tmp0d, .sia(-4, .dst0, .add_unaligned_size), ._, ._ },
91128 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"4", .tmp0), ._, ._ },
91129 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91130 .{ ._, .v_ss, .mov, .memi(.dst0d, .tmp0), .tmp3x, ._, ._ },
91131 .{ ._, ._, .sub, .tmp0d, .si(4), ._, ._ },
91132 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91133 } },
91134 }, .{
91135 .required_cc_abi = .win64,
91136 .required_features = .{ .sse, null, null, null },
91137 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91138 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .dword, .is = .dword } }, .any },
91139 .patterns = &.{
91140 .{ .src = .{ .to_mem, .none, .none } },
91141 },
91142 .call_frame = .{ .alignment = .@"16" },
91143 .extra_temps = .{
91144 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
91145 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91146 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfsf2" } },
91147 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91148 .unused,
91149 .unused,
91150 .unused,
91151 .unused,
91152 .unused,
91153 .unused,
91154 .unused,
91155 },
91156 .dst_temps = .{ .mem, .unused },
91157 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
91158 .each = .{ .once = &.{
91159 .{ ._, ._, .mov, .tmp0d, .sia(-4, .dst0, .add_unaligned_size), ._, ._ },
91160 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"4", .tmp0), ._, ._ },
91161 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91162 .{ ._, ._ss, .mov, .memi(.dst0d, .tmp0), .tmp3x, ._, ._ },
91163 .{ ._, ._, .sub, .tmp0d, .si(4), ._, ._ },
91164 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91165 } },
91166 }, .{
91167 .required_cc_abi = .sysv64,
8896591168 .required_features = .{ .sse, null, null, null },
8896691169 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8896791170 .dst_constraints = .{ .{ .scalar_float = .{ .of = .qword, .is = .qword } }, .any },
......@@ -88988,6 +91191,35 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8898891191 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
8898991192 } },
8899091193 }, .{
91194 .required_cc_abi = .win64,
91195 .required_features = .{ .sse, null, null, null },
91196 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91197 .dst_constraints = .{ .{ .scalar_float = .{ .of = .qword, .is = .qword } }, .any },
91198 .patterns = &.{
91199 .{ .src = .{ .to_mem, .none, .none } },
91200 },
91201 .call_frame = .{ .alignment = .@"16" },
91202 .extra_temps = .{
91203 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91204 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
91205 .unused,
91206 .unused,
91207 .unused,
91208 .unused,
91209 .unused,
91210 .unused,
91211 .unused,
91212 .unused,
91213 .unused,
91214 },
91215 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
91216 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
91217 .each = .{ .once = &.{
91218 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
91219 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
91220 } },
91221 }, .{
91222 .required_cc_abi = .sysv64,
8899191223 .required_features = .{ .avx, null, null, null },
8899291224 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8899391225 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
......@@ -89019,6 +91251,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8901991251 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8902091252 } },
8902191253 }, .{
91254 .required_cc_abi = .sysv64,
8902291255 .required_features = .{ .sse2, null, null, null },
8902391256 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8902491257 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
......@@ -89050,6 +91283,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8905091283 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8905191284 } },
8905291285 }, .{
91286 .required_cc_abi = .sysv64,
8905391287 .required_features = .{ .sse, null, null, null },
8905491288 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8905591289 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
......@@ -89081,46 +91315,83 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8908191315 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8908291316 } },
8908391317 }, .{
89084 .required_cc_abi = .sysv64,
89085 .required_features = .{ .sse, .x87, null, null },
89086 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
89087 .dst_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
91318 .required_cc_abi = .win64,
91319 .required_features = .{ .avx, null, null, null },
91320 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91321 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
8908891322 .patterns = &.{
89089 .{ .src = .{ .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .none, .none } },
91323 .{ .src = .{ .to_mem, .none, .none } },
8909091324 },
8909191325 .call_frame = .{ .alignment = .@"16" },
8909291326 .extra_temps = .{
89093 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
91327 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
91328 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91329 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
91330 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91331 .unused,
91332 .unused,
8909491333 .unused,
8909591334 .unused,
8909691335 .unused,
8909791336 .unused,
8909891337 .unused,
91338 },
91339 .dst_temps = .{ .mem, .unused },
91340 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
91341 .each = .{ .once = &.{
91342 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_unaligned_size), ._, ._ },
91343 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"2", .tmp0), ._, ._ },
91344 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91345 .{ ._, .v_sd, .mov, .memi(.dst0q, .tmp0), .tmp3x, ._, ._ },
91346 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
91347 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91348 } },
91349 }, .{
91350 .required_cc_abi = .win64,
91351 .required_features = .{ .sse2, null, null, null },
91352 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91353 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
91354 .patterns = &.{
91355 .{ .src = .{ .to_mem, .none, .none } },
91356 },
91357 .call_frame = .{ .alignment = .@"16" },
91358 .extra_temps = .{
91359 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
91360 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91361 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
91362 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
91363 .unused,
91364 .unused,
8909991365 .unused,
8910091366 .unused,
8910191367 .unused,
8910291368 .unused,
8910391369 .unused,
8910491370 },
89105 .dst_temps = .{ .{ .reg = .st0 }, .unused },
91371 .dst_temps = .{ .mem, .unused },
8910691372 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8910791373 .each = .{ .once = &.{
89108 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
91374 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_unaligned_size), ._, ._ },
91375 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"2", .tmp0), ._, ._ },
91376 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91377 .{ ._, ._sd, .mov, .memi(.dst0q, .tmp0), .tmp3x, ._, ._ },
91378 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
91379 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8910991380 } },
8911091381 }, .{
8911191382 .required_cc_abi = .win64,
8911291383 .required_features = .{ .sse, null, null, null },
89113 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
89114 .dst_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
91384 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91385 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .qword, .is = .qword } }, .any },
8911591386 .patterns = &.{
89116 .{ .src = .{ .{ .to_reg = .xmm1 }, .none, .none } },
91387 .{ .src = .{ .to_mem, .none, .none } },
8911791388 },
8911891389 .call_frame = .{ .alignment = .@"16" },
8911991390 .extra_temps = .{
91391 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
8912091392 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
89121 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
89122 .unused,
89123 .unused,
91393 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfdf2" } },
91394 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8912491395 .unused,
8912591396 .unused,
8912691397 .unused,
......@@ -89132,21 +91403,23 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8913291403 .dst_temps = .{ .mem, .unused },
8913391404 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8913491405 .each = .{ .once = &.{
89135 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
89136 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
91406 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_unaligned_size), ._, ._ },
91407 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"2", .tmp0), ._, ._ },
91408 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91409 .{ ._, ._ps, .movl, .memi(.dst0q, .tmp0), .tmp3x, ._, ._ },
91410 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
91411 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8913791412 } },
8913891413 }, .{
8913991414 .required_cc_abi = .sysv64,
89140 .required_features = .{ .avx, null, null, null },
89141 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
89142 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
91415 .required_features = .{ .sse, .x87, null, null },
91416 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91417 .dst_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
8914391418 .patterns = &.{
89144 .{ .src = .{ .to_mem, .none, .none } },
91419 .{ .src = .{ .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .none, .none } },
8914591420 },
8914691421 .call_frame = .{ .alignment = .@"16" },
8914791422 .extra_temps = .{
89148 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
89149 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8915091423 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
8915191424 .unused,
8915291425 .unused,
......@@ -89156,31 +91429,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8915691429 .unused,
8915791430 .unused,
8915891431 .unused,
91432 .unused,
91433 .unused,
8915991434 },
89160 .dst_temps = .{ .mem, .unused },
91435 .dst_temps = .{ .{ .reg = .st0 }, .unused },
8916191436 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8916291437 .each = .{ .once = &.{
89163 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_unaligned_size), ._, ._ },
89164 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
89165 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
89166 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
89167 .{ ._, .f_p, .st, .memi(.dst0t, .tmp0), ._, ._, ._ },
89168 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
89169 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91438 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
8917091439 } },
8917191440 }, .{
8917291441 .required_cc_abi = .win64,
89173 .required_features = .{ .avx, null, null, null },
89174 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
89175 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
91442 .required_features = .{ .sse, null, null, null },
91443 .src_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
91444 .dst_constraints = .{ .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
8917691445 .patterns = &.{
8917791446 .{ .src = .{ .to_mem, .none, .none } },
8917891447 },
8917991448 .call_frame = .{ .alignment = .@"16" },
8918091449 .extra_temps = .{
89181 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
8918291450 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
89183 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
91451 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8918491452 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
8918591453 .unused,
8918691454 .unused,
......@@ -89189,20 +91457,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8918991457 .unused,
8919091458 .unused,
8919191459 .unused,
91460 .unused,
8919291461 },
8919391462 .dst_temps = .{ .mem, .unused },
8919491463 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8919591464 .each = .{ .once = &.{
89196 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_unaligned_size), ._, ._ },
89197 .{ .@"0:", ._, .lea, .tmp1p, .memi(.dst0, .tmp0), ._, ._ },
89198 .{ ._, .v_dqa, .mov, .tmp2x, .memi(.src0x, .tmp0), ._, ._ },
89199 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
89200 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
89201 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91465 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
91466 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
91467 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
8920291468 } },
8920391469 }, .{
8920491470 .required_cc_abi = .sysv64,
89205 .required_features = .{ .sse2, null, null, null },
91471 .required_features = .{ .avx, null, null, null },
8920691472 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8920791473 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
8920891474 .patterns = &.{
......@@ -89226,7 +91492,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8922691492 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8922791493 .each = .{ .once = &.{
8922891494 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_unaligned_size), ._, ._ },
89229 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
91495 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
8923091496 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
8923191497 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
8923291498 .{ ._, .f_p, .st, .memi(.dst0t, .tmp0), ._, ._, ._ },
......@@ -89234,7 +91500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8923491500 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8923591501 } },
8923691502 }, .{
89237 .required_cc_abi = .win64,
91503 .required_cc_abi = .sysv64,
8923891504 .required_features = .{ .sse2, null, null, null },
8923991505 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
8924091506 .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, .any },
......@@ -89244,8 +91510,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8924491510 .call_frame = .{ .alignment = .@"16" },
8924591511 .extra_temps = .{
8924691512 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
89247 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
89248 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
91513 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
8924991514 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
8925091515 .unused,
8925191516 .unused,
......@@ -89254,14 +91519,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8925491519 .unused,
8925591520 .unused,
8925691521 .unused,
91522 .unused,
8925791523 },
8925891524 .dst_temps = .{ .mem, .unused },
8925991525 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8926091526 .each = .{ .once = &.{
8926191527 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_unaligned_size), ._, ._ },
89262 .{ .@"0:", ._, .lea, .tmp1p, .memi(.dst0, .tmp0), ._, ._ },
89263 .{ ._, ._dqa, .mov, .tmp2x, .memi(.src0x, .tmp0), ._, ._ },
89264 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
91528 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
91529 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
91530 .{ .pseudo, .f_cstp, .de, ._, ._, ._, ._ },
91531 .{ ._, .f_p, .st, .memi(.dst0t, .tmp0), ._, ._, ._ },
8926591532 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
8926691533 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8926791534 } },
......@@ -89310,7 +91577,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8931091577 .extra_temps = .{
8931191578 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
8931291579 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
89313 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } },
91580 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
8931491581 .{ .type = .usize, .kind = .{ .extern_func = "__trunctfxf2" } },
8931591582 .unused,
8931691583 .unused,
......@@ -89323,9 +91590,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8932391590 .dst_temps = .{ .mem, .unused },
8932491591 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
8932591592 .each = .{ .once = &.{
89326 .{ ._, ._, .mov, .tmp0d, .sa(.dst0, .add_unaligned_size), ._, ._ },
91593 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_unaligned_size), ._, ._ },
8932791594 .{ .@"0:", ._, .lea, .tmp1p, .memi(.dst0, .tmp0), ._, ._ },
89328 .{ ._, ._ps, .mova, .tmp2x, .memi(.src0x, .tmp0), ._, ._ },
91595 .{ ._, ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
8932991596 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
8933091597 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
8933191598 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
......@@ -110769,6 +113036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110769113036 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
110770113037 } },
110771113038 }, .{
113039 .required_cc_abi = .sysv64,
110772113040 .required_features = .{ .avx, .slow_incdec, null, null },
110773113041 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110774113042 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110802,6 +113070,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110802113070 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
110803113071 } },
110804113072 }, .{
113073 .required_cc_abi = .sysv64,
110805113074 .required_features = .{ .avx, null, null, null },
110806113075 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110807113076 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110835,6 +113104,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110835113104 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
110836113105 } },
110837113106 }, .{
113107 .required_cc_abi = .sysv64,
110838113108 .required_features = .{ .sse2, .slow_incdec, null, null },
110839113109 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110840113110 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110868,6 +113138,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110868113138 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
110869113139 } },
110870113140 }, .{
113141 .required_cc_abi = .sysv64,
110871113142 .required_features = .{ .sse2, null, null, null },
110872113143 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110873113144 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110901,6 +113172,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110901113172 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
110902113173 } },
110903113174 }, .{
113175 .required_cc_abi = .sysv64,
110904113176 .required_features = .{ .sse, .slow_incdec, null, null },
110905113177 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110906113178 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110934,6 +113206,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110934113206 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
110935113207 } },
110936113208 }, .{
113209 .required_cc_abi = .sysv64,
110937113210 .required_features = .{ .sse, null, null, null },
110938113211 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110939113212 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
......@@ -110967,6 +113240,75 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110967113240 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
110968113241 } },
110969113242 }, .{
113243 .required_cc_abi = .win64,
113244 .required_features = .{ .sse, .slow_incdec, null, null },
113245 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
113246 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
113247 .patterns = &.{
113248 .{ .src = .{ .to_mem, .none, .none } },
113249 },
113250 .call_frame = .{ .alignment = .@"16" },
113251 .extra_temps = .{
113252 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
113253 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
113254 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113255 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
113256 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113257 .unused,
113258 .unused,
113259 .unused,
113260 .unused,
113261 .unused,
113262 .unused,
113263 },
113264 .dst_temps = .{ .mem, .unused },
113265 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113266 .each = .{ .once = &.{
113267 .{ ._, ._, .lea, .tmp0p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
113268 .{ ._, ._, .mov, .tmp1d, .sia(-1, .dst0, .add_unaligned_size), ._, ._ },
113269 .{ .@"0:", ._, .mov, .tmp2p, .tmp0p, ._, ._ },
113270 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
113271 .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp4b, ._, ._ },
113272 .{ ._, ._, .lea, .tmp0p, .lead(.tmp0, -16), ._, ._ },
113273 .{ ._, ._, .sub, .tmp1d, .si(1), ._, ._ },
113274 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
113275 } },
113276 }, .{
113277 .required_cc_abi = .win64,
113278 .required_features = .{ .sse, null, null, null },
113279 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
113280 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .byte, .is = .byte } }, .any },
113281 .patterns = &.{
113282 .{ .src = .{ .to_mem, .none, .none } },
113283 },
113284 .call_frame = .{ .alignment = .@"16" },
113285 .extra_temps = .{
113286 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
113287 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
113288 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113289 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
113290 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113291 .unused,
113292 .unused,
113293 .unused,
113294 .unused,
113295 .unused,
113296 .unused,
113297 },
113298 .dst_temps = .{ .mem, .unused },
113299 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113300 .each = .{ .once = &.{
113301 .{ ._, ._, .lea, .tmp0p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
113302 .{ ._, ._, .mov, .tmp1d, .sia(-1, .dst0, .add_unaligned_size), ._, ._ },
113303 .{ .@"0:", ._, .mov, .tmp2p, .tmp0p, ._, ._ },
113304 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
113305 .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp4b, ._, ._ },
113306 .{ ._, ._, .lea, .tmp0p, .lead(.tmp0, -16), ._, ._ },
113307 .{ ._, ._c, .de, .tmp1d, ._, ._, ._ },
113308 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
113309 } },
113310 }, .{
113311 .required_cc_abi = .sysv64,
110970113312 .required_features = .{ .avx, null, null, null },
110971113313 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
110972113314 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .word, .is = .word } }, .any },
......@@ -110998,6 +113340,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
110998113340 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
110999113341 } },
111000113342 }, .{
113343 .required_cc_abi = .sysv64,
111001113344 .required_features = .{ .sse2, null, null, null },
111002113345 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111003113346 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .word, .is = .word } }, .any },
......@@ -111029,6 +113372,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111029113372 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111030113373 } },
111031113374 }, .{
113375 .required_cc_abi = .sysv64,
111032113376 .required_features = .{ .sse, null, null, null },
111033113377 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111034113378 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .word, .is = .word } }, .any },
......@@ -111060,6 +113404,39 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111060113404 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111061113405 } },
111062113406 }, .{
113407 .required_cc_abi = .win64,
113408 .required_features = .{ .sse, null, null, null },
113409 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
113410 .dst_constraints = .{ .{ .multiple_scalar_int = .{ .of = .word, .is = .word } }, .any },
113411 .patterns = &.{
113412 .{ .src = .{ .to_mem, .none, .none } },
113413 },
113414 .call_frame = .{ .alignment = .@"16" },
113415 .extra_temps = .{
113416 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
113417 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113418 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
113419 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113420 .unused,
113421 .unused,
113422 .unused,
113423 .unused,
113424 .unused,
113425 .unused,
113426 .unused,
113427 },
113428 .dst_temps = .{ .mem, .unused },
113429 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113430 .each = .{ .once = &.{
113431 .{ ._, ._, .mov, .tmp0d, .sia(-2, .dst0, .add_unaligned_size), ._, ._ },
113432 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"8", .tmp0), ._, ._ },
113433 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
113434 .{ ._, ._, .mov, .memi(.dst0w, .tmp0), .tmp3w, ._, ._ },
113435 .{ ._, ._, .sub, .tmp0d, .si(2), ._, ._ },
113436 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
113437 } },
113438 }, .{
113439 .required_cc_abi = .sysv64,
111063113440 .required_features = .{ .sse, null, null, null },
111064113441 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111065113442 .dst_constraints = .{ .{ .signed_int = .dword }, .any },
......@@ -111086,6 +113463,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111086113463 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
111087113464 } },
111088113465 }, .{
113466 .required_cc_abi = .sysv64,
111089113467 .required_features = .{ .sse, null, null, null },
111090113468 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111091113469 .dst_constraints = .{ .{ .unsigned_int = .dword }, .any },
......@@ -111112,6 +113490,63 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111112113490 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
111113113491 } },
111114113492 }, .{
113493 .required_cc_abi = .win64,
113494 .required_features = .{ .sse, null, null, null },
113495 .src_constraints = .{ .{ .float = .xword }, .any, .any },
113496 .dst_constraints = .{ .{ .signed_int = .dword }, .any },
113497 .patterns = &.{
113498 .{ .src = .{ .to_mem, .none, .none } },
113499 },
113500 .call_frame = .{ .alignment = .@"16" },
113501 .extra_temps = .{
113502 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113503 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
113504 .unused,
113505 .unused,
113506 .unused,
113507 .unused,
113508 .unused,
113509 .unused,
113510 .unused,
113511 .unused,
113512 .unused,
113513 },
113514 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
113515 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113516 .each = .{ .once = &.{
113517 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
113518 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
113519 } },
113520 }, .{
113521 .required_cc_abi = .win64,
113522 .required_features = .{ .sse, null, null, null },
113523 .src_constraints = .{ .{ .float = .xword }, .any, .any },
113524 .dst_constraints = .{ .{ .unsigned_int = .dword }, .any },
113525 .patterns = &.{
113526 .{ .src = .{ .to_mem, .none, .none } },
113527 },
113528 .call_frame = .{ .alignment = .@"16" },
113529 .extra_temps = .{
113530 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113531 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
113532 .unused,
113533 .unused,
113534 .unused,
113535 .unused,
113536 .unused,
113537 .unused,
113538 .unused,
113539 .unused,
113540 .unused,
113541 },
113542 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
113543 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113544 .each = .{ .once = &.{
113545 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
113546 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
113547 } },
113548 }, .{
113549 .required_cc_abi = .sysv64,
111115113550 .required_features = .{ .avx, null, null, null },
111116113551 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111117113552 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111143,6 +113578,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111143113578 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111144113579 } },
111145113580 }, .{
113581 .required_cc_abi = .sysv64,
111146113582 .required_features = .{ .avx, null, null, null },
111147113583 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111148113584 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111174,6 +113610,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111174113610 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111175113611 } },
111176113612 }, .{
113613 .required_cc_abi = .sysv64,
111177113614 .required_features = .{ .sse2, null, null, null },
111178113615 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111179113616 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111205,6 +113642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111205113642 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111206113643 } },
111207113644 }, .{
113645 .required_cc_abi = .sysv64,
111208113646 .required_features = .{ .sse2, null, null, null },
111209113647 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111210113648 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111236,6 +113674,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111236113674 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111237113675 } },
111238113676 }, .{
113677 .required_cc_abi = .sysv64,
111239113678 .required_features = .{ .sse, null, null, null },
111240113679 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111241113680 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111267,6 +113706,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111267113706 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111268113707 } },
111269113708 }, .{
113709 .required_cc_abi = .sysv64,
111270113710 .required_features = .{ .sse, null, null, null },
111271113711 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111272113712 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -111298,6 +113738,71 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111298113738 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111299113739 } },
111300113740 }, .{
113741 .required_cc_abi = .win64,
113742 .required_features = .{ .sse, null, null, null },
113743 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
113744 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .dword, .is = .dword } }, .any },
113745 .patterns = &.{
113746 .{ .src = .{ .to_mem, .none, .none } },
113747 },
113748 .call_frame = .{ .alignment = .@"16" },
113749 .extra_temps = .{
113750 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
113751 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113752 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfsi" } },
113753 .{ .type = .i32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113754 .unused,
113755 .unused,
113756 .unused,
113757 .unused,
113758 .unused,
113759 .unused,
113760 .unused,
113761 },
113762 .dst_temps = .{ .mem, .unused },
113763 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113764 .each = .{ .once = &.{
113765 .{ ._, ._, .mov, .tmp0d, .sia(-4, .dst0, .add_unaligned_size), ._, ._ },
113766 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"4", .tmp0), ._, ._ },
113767 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
113768 .{ ._, ._, .mov, .memi(.dst0d, .tmp0), .tmp3d, ._, ._ },
113769 .{ ._, ._, .sub, .tmp0d, .si(4), ._, ._ },
113770 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
113771 } },
113772 }, .{
113773 .required_cc_abi = .win64,
113774 .required_features = .{ .sse, null, null, null },
113775 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
113776 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
113777 .patterns = &.{
113778 .{ .src = .{ .to_mem, .none, .none } },
113779 },
113780 .call_frame = .{ .alignment = .@"16" },
113781 .extra_temps = .{
113782 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
113783 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113784 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfsi" } },
113785 .{ .type = .u32, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113786 .unused,
113787 .unused,
113788 .unused,
113789 .unused,
113790 .unused,
113791 .unused,
113792 .unused,
113793 },
113794 .dst_temps = .{ .mem, .unused },
113795 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113796 .each = .{ .once = &.{
113797 .{ ._, ._, .mov, .tmp0d, .sia(-4, .dst0, .add_unaligned_size), ._, ._ },
113798 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"4", .tmp0), ._, ._ },
113799 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
113800 .{ ._, ._, .mov, .memi(.dst0d, .tmp0), .tmp3d, ._, ._ },
113801 .{ ._, ._, .sub, .tmp0d, .si(4), ._, ._ },
113802 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
113803 } },
113804 }, .{
113805 .required_cc_abi = .sysv64,
111301113806 .required_features = .{ .@"64bit", .sse, null, null },
111302113807 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111303113808 .dst_constraints = .{ .{ .signed_int = .qword }, .any },
......@@ -111324,6 +113829,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111324113829 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
111325113830 } },
111326113831 }, .{
113832 .required_cc_abi = .sysv64,
111327113833 .required_features = .{ .@"64bit", .sse, null, null },
111328113834 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111329113835 .dst_constraints = .{ .{ .unsigned_int = .qword }, .any },
......@@ -111350,6 +113856,63 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111350113856 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
111351113857 } },
111352113858 }, .{
113859 .required_cc_abi = .win64,
113860 .required_features = .{ .@"64bit", .sse, null, null },
113861 .src_constraints = .{ .{ .float = .xword }, .any, .any },
113862 .dst_constraints = .{ .{ .signed_int = .qword }, .any },
113863 .patterns = &.{
113864 .{ .src = .{ .to_mem, .none, .none } },
113865 },
113866 .call_frame = .{ .alignment = .@"16" },
113867 .extra_temps = .{
113868 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113869 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
113870 .unused,
113871 .unused,
113872 .unused,
113873 .unused,
113874 .unused,
113875 .unused,
113876 .unused,
113877 .unused,
113878 .unused,
113879 },
113880 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
113881 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113882 .each = .{ .once = &.{
113883 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
113884 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
113885 } },
113886 }, .{
113887 .required_cc_abi = .win64,
113888 .required_features = .{ .@"64bit", .sse, null, null },
113889 .src_constraints = .{ .{ .float = .xword }, .any, .any },
113890 .dst_constraints = .{ .{ .unsigned_int = .qword }, .any },
113891 .patterns = &.{
113892 .{ .src = .{ .to_mem, .none, .none } },
113893 },
113894 .call_frame = .{ .alignment = .@"16" },
113895 .extra_temps = .{
113896 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
113897 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
113898 .unused,
113899 .unused,
113900 .unused,
113901 .unused,
113902 .unused,
113903 .unused,
113904 .unused,
113905 .unused,
113906 .unused,
113907 },
113908 .dst_temps = .{ .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
113909 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
113910 .each = .{ .once = &.{
113911 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
113912 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
113913 } },
113914 }, .{
113915 .required_cc_abi = .sysv64,
111353113916 .required_features = .{ .@"64bit", .avx, null, null },
111354113917 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111355113918 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111381,6 +113944,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111381113944 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111382113945 } },
111383113946 }, .{
113947 .required_cc_abi = .sysv64,
111384113948 .required_features = .{ .@"64bit", .avx, null, null },
111385113949 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111386113950 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111412,6 +113976,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111412113976 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111413113977 } },
111414113978 }, .{
113979 .required_cc_abi = .sysv64,
111415113980 .required_features = .{ .@"64bit", .sse2, null, null },
111416113981 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111417113982 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111443,6 +114008,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111443114008 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111444114009 } },
111445114010 }, .{
114011 .required_cc_abi = .sysv64,
111446114012 .required_features = .{ .@"64bit", .sse2, null, null },
111447114013 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111448114014 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111474,6 +114040,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111474114040 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111475114041 } },
111476114042 }, .{
114043 .required_cc_abi = .sysv64,
111477114044 .required_features = .{ .@"64bit", .sse, null, null },
111478114045 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111479114046 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111505,6 +114072,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111505114072 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111506114073 } },
111507114074 }, .{
114075 .required_cc_abi = .sysv64,
111508114076 .required_features = .{ .@"64bit", .sse, null, null },
111509114077 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111510114078 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } }, .any },
......@@ -111536,16 +114104,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111536114104 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111537114105 } },
111538114106 }, .{
111539 .required_cc_abi = .sysv64,
111540 .required_features = .{ .sse, null, null, null },
111541 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111542 .dst_constraints = .{ .{ .signed_int = .xword }, .any },
114107 .required_cc_abi = .win64,
114108 .required_features = .{ .@"64bit", .sse, null, null },
114109 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
114110 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .qword, .is = .qword } }, .any },
111543114111 .patterns = &.{
111544 .{ .src = .{ .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .none, .none } },
114112 .{ .src = .{ .to_mem, .none, .none } },
111545114113 },
111546114114 .call_frame = .{ .alignment = .@"16" },
111547114115 .extra_temps = .{
111548 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
114116 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
114117 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114118 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfdi" } },
114119 .{ .type = .i64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111549114120 .unused,
111550114121 .unused,
111551114122 .unused,
......@@ -111553,17 +114124,51 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111553114124 .unused,
111554114125 .unused,
111555114126 .unused,
114127 },
114128 .dst_temps = .{ .mem, .unused },
114129 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
114130 .each = .{ .once = &.{
114131 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_unaligned_size), ._, ._ },
114132 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"2", .tmp0), ._, ._ },
114133 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
114134 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
114135 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
114136 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
114137 } },
114138 }, .{
114139 .required_cc_abi = .win64,
114140 .required_features = .{ .@"64bit", .sse, null, null },
114141 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
114142 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .qword, .is = .qword } }, .any },
114143 .patterns = &.{
114144 .{ .src = .{ .to_mem, .none, .none } },
114145 },
114146 .call_frame = .{ .alignment = .@"16" },
114147 .extra_temps = .{
114148 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
114149 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114150 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfdi" } },
114151 .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114152 .unused,
114153 .unused,
114154 .unused,
114155 .unused,
111556114156 .unused,
111557114157 .unused,
111558114158 .unused,
111559114159 },
111560 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
114160 .dst_temps = .{ .mem, .unused },
111561114161 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111562114162 .each = .{ .once = &.{
111563 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
114163 .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_unaligned_size), ._, ._ },
114164 .{ .@"0:", ._, .lea, .tmp1p, .memsi(.src0, .@"2", .tmp0), ._, ._ },
114165 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
114166 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
114167 .{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
114168 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111564114169 } },
111565114170 }, .{
111566 .required_cc_abi = .win64,
114171 .required_cc_abi = .sysv64,
111567114172 .required_features = .{ .sse, null, null, null },
111568114173 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111569114174 .dst_constraints = .{ .{ .signed_int = .xword }, .any },
......@@ -111584,7 +114189,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111584114189 .unused,
111585114190 .unused,
111586114191 },
111587 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
114192 .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
111588114193 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111589114194 .each = .{ .once = &.{
111590114195 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
......@@ -111616,16 +114221,45 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111616114221 .each = .{ .once = &.{
111617114222 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
111618114223 } },
114224 }, .{
114225 .required_cc_abi = .win64,
114226 .required_features = .{ .sse, null, null, null },
114227 .src_constraints = .{ .{ .float = .xword }, .any, .any },
114228 .dst_constraints = .{ .{ .signed_int = .xword }, .any },
114229 .patterns = &.{
114230 .{ .src = .{ .to_mem, .none, .none } },
114231 },
114232 .call_frame = .{ .alignment = .@"16" },
114233 .extra_temps = .{
114234 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114235 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
114236 .unused,
114237 .unused,
114238 .unused,
114239 .unused,
114240 .unused,
114241 .unused,
114242 .unused,
114243 .unused,
114244 .unused,
114245 },
114246 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
114247 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
114248 .each = .{ .once = &.{
114249 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
114250 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
114251 } },
111619114252 }, .{
111620114253 .required_cc_abi = .win64,
111621114254 .required_features = .{ .sse, null, null, null },
111622114255 .src_constraints = .{ .{ .float = .xword }, .any, .any },
111623114256 .dst_constraints = .{ .{ .unsigned_int = .xword }, .any },
111624114257 .patterns = &.{
111625 .{ .src = .{ .{ .to_param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .none, .none } },
114258 .{ .src = .{ .to_mem, .none, .none } },
111626114259 },
111627114260 .call_frame = .{ .alignment = .@"16" },
111628114261 .extra_temps = .{
114262 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111629114263 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111630114264 .unused,
111631114265 .unused,
......@@ -111636,12 +114270,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111636114270 .unused,
111637114271 .unused,
111638114272 .unused,
111639 .unused,
111640114273 },
111641114274 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
111642114275 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111643114276 .each = .{ .once = &.{
111644 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
114277 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
114278 .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
111645114279 } },
111646114280 }, .{
111647114281 .required_cc_abi = .sysv64,
......@@ -111677,10 +114311,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111677114311 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111678114312 } },
111679114313 }, .{
111680 .required_cc_abi = .win64,
114314 .required_cc_abi = .sysv64,
111681114315 .required_features = .{ .avx, null, null, null },
111682114316 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111683 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
114317 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
111684114318 .patterns = &.{
111685114319 .{ .src = .{ .to_mem, .none, .none } },
111686114320 },
......@@ -111688,8 +114322,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111688114322 .extra_temps = .{
111689114323 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111690114324 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111691 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
111692 .unused,
114325 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
114326 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111693114327 .unused,
111694114328 .unused,
111695114329 .unused,
......@@ -111704,15 +114338,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111704114338 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111705114339 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
111706114340 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111707 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
114341 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
114342 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
111708114343 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111709114344 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111710114345 } },
111711114346 }, .{
111712114347 .required_cc_abi = .sysv64,
111713 .required_features = .{ .avx, null, null, null },
114348 .required_features = .{ .sse2, null, null, null },
111714114349 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111715 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
114350 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
111716114351 .patterns = &.{
111717114352 .{ .src = .{ .to_mem, .none, .none } },
111718114353 },
......@@ -111720,8 +114355,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111720114355 .extra_temps = .{
111721114356 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111722114357 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111723 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111724 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114358 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
114359 .{ .type = .i128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111725114360 .unused,
111726114361 .unused,
111727114362 .unused,
......@@ -111734,7 +114369,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111734114369 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111735114370 .each = .{ .once = &.{
111736114371 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111737 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114372 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
111738114373 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111739114374 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
111740114375 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
......@@ -111742,8 +114377,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111742114377 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111743114378 } },
111744114379 }, .{
111745 .required_cc_abi = .win64,
111746 .required_features = .{ .avx, null, null, null },
114380 .required_cc_abi = .sysv64,
114381 .required_features = .{ .sse2, null, null, null },
111747114382 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111748114383 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
111749114384 .patterns = &.{
......@@ -111754,7 +114389,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111754114389 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111755114390 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111756114391 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111757 .unused,
114392 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111758114393 .unused,
111759114394 .unused,
111760114395 .unused,
......@@ -111767,15 +114402,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111767114402 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111768114403 .each = .{ .once = &.{
111769114404 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111770 .{ .@"0:", .v_dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114405 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
111771114406 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111772 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
114407 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
114408 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
111773114409 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111774114410 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111775114411 } },
111776114412 }, .{
111777114413 .required_cc_abi = .sysv64,
111778 .required_features = .{ .sse2, null, null, null },
114414 .required_features = .{ .sse, null, null, null },
111779114415 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111780114416 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
111781114417 .patterns = &.{
......@@ -111799,7 +114435,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111799114435 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111800114436 .each = .{ .once = &.{
111801114437 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111802 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114438 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
111803114439 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111804114440 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
111805114441 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
......@@ -111807,10 +114443,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111807114443 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111808114444 } },
111809114445 }, .{
111810 .required_cc_abi = .win64,
111811 .required_features = .{ .sse2, null, null, null },
114446 .required_cc_abi = .sysv64,
114447 .required_features = .{ .sse, null, null, null },
111812114448 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111813 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
114449 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
111814114450 .patterns = &.{
111815114451 .{ .src = .{ .to_mem, .none, .none } },
111816114452 },
......@@ -111818,8 +114454,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111818114454 .extra_temps = .{
111819114455 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111820114456 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111821 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
111822 .unused,
114457 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
114458 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111823114459 .unused,
111824114460 .unused,
111825114461 .unused,
......@@ -111832,26 +114468,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111832114468 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111833114469 .each = .{ .once = &.{
111834114470 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111835 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114471 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
111836114472 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111837 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
114473 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
114474 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
111838114475 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111839114476 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111840114477 } },
111841114478 }, .{
111842 .required_cc_abi = .sysv64,
111843 .required_features = .{ .sse2, null, null, null },
114479 .required_cc_abi = .win64,
114480 .required_features = .{ .avx, null, null, null },
111844114481 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111845 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
114482 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
111846114483 .patterns = &.{
111847114484 .{ .src = .{ .to_mem, .none, .none } },
111848114485 },
111849114486 .call_frame = .{ .alignment = .@"16" },
111850114487 .extra_temps = .{
111851114488 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111852 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111853 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111854 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114489 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114490 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
114491 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111855114492 .unused,
111856114493 .unused,
111857114494 .unused,
......@@ -111864,16 +114501,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111864114501 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111865114502 .each = .{ .once = &.{
111866114503 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111867 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114504 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
111868114505 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111869 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
111870 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
114506 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
111871114507 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111872114508 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111873114509 } },
111874114510 }, .{
111875114511 .required_cc_abi = .win64,
111876 .required_features = .{ .sse2, null, null, null },
114512 .required_features = .{ .avx, null, null, null },
111877114513 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111878114514 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
111879114515 .patterns = &.{
......@@ -111882,9 +114518,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111882114518 .call_frame = .{ .alignment = .@"16" },
111883114519 .extra_temps = .{
111884114520 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111885 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114521 .{ .type = .f128, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111886114522 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111887 .unused,
114523 .{ .type = .u128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111888114524 .unused,
111889114525 .unused,
111890114526 .unused,
......@@ -111897,15 +114533,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111897114533 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111898114534 .each = .{ .once = &.{
111899114535 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111900 .{ .@"0:", ._dqa, .mov, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114536 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
111901114537 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111902 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
114538 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
111903114539 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111904114540 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111905114541 } },
111906114542 }, .{
111907 .required_cc_abi = .sysv64,
111908 .required_features = .{ .sse, null, null, null },
114543 .required_cc_abi = .win64,
114544 .required_features = .{ .sse2, null, null, null },
111909114545 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111910114546 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
111911114547 .patterns = &.{
......@@ -111914,9 +114550,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111914114550 .call_frame = .{ .alignment = .@"16" },
111915114551 .extra_temps = .{
111916114552 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111917 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114553 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111918114554 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
111919 .{ .type = .i128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114555 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111920114556 .unused,
111921114557 .unused,
111922114558 .unused,
......@@ -111929,27 +114565,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111929114565 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111930114566 .each = .{ .once = &.{
111931114567 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111932 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114568 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
111933114569 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111934 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
111935 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
114570 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
111936114571 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111937114572 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111938114573 } },
111939114574 }, .{
111940114575 .required_cc_abi = .win64,
111941 .required_features = .{ .sse, null, null, null },
114576 .required_features = .{ .sse2, null, null, null },
111942114577 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111943 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
114578 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
111944114579 .patterns = &.{
111945114580 .{ .src = .{ .to_mem, .none, .none } },
111946114581 },
111947114582 .call_frame = .{ .alignment = .@"16" },
111948114583 .extra_temps = .{
111949114584 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111950 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111951 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
111952 .unused,
114585 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114586 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
114587 .{ .type = .u128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111953114588 .unused,
111954114589 .unused,
111955114590 .unused,
......@@ -111962,26 +114597,26 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111962114597 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111963114598 .each = .{ .once = &.{
111964114599 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111965 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114600 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
111966114601 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111967 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
114602 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
111968114603 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
111969114604 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111970114605 } },
111971114606 }, .{
111972 .required_cc_abi = .sysv64,
114607 .required_cc_abi = .win64,
111973114608 .required_features = .{ .sse, null, null, null },
111974114609 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
111975 .dst_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any },
114610 .dst_constraints = .{ .{ .multiple_scalar_signed_int = .{ .of = .xword, .is = .xword } }, .any },
111976114611 .patterns = &.{
111977114612 .{ .src = .{ .to_mem, .none, .none } },
111978114613 },
111979114614 .call_frame = .{ .alignment = .@"16" },
111980114615 .extra_temps = .{
111981114616 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
111982 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111983 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
111984 .{ .type = .u128, .kind = .{ .ret_gpr_pair = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114617 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114618 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfti" } },
114619 .{ .type = .i128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
111985114620 .unused,
111986114621 .unused,
111987114622 .unused,
......@@ -111994,10 +114629,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111994114629 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
111995114630 .each = .{ .once = &.{
111996114631 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
111997 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114632 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
111998114633 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
111999 .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q0, ._, ._ },
112000 .{ ._, ._, .mov, .memid(.dst0q, .tmp0, 8), .tmp3q1, ._, ._ },
114634 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ },
112001114635 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
112002114636 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112003114637 } },
......@@ -112012,9 +114646,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112012114646 .call_frame = .{ .alignment = .@"16" },
112013114647 .extra_temps = .{
112014114648 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
112015 .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114649 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
112016114650 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfti" } },
112017 .unused,
114651 .{ .type = .u128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
112018114652 .unused,
112019114653 .unused,
112020114654 .unused,
......@@ -112027,13 +114661,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112027114661 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
112028114662 .each = .{ .once = &.{
112029114663 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
112030 .{ .@"0:", ._ps, .mova, .tmp1x, .memi(.src0x, .tmp0), ._, ._ },
114664 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
112031114665 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
112032114666 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
112033114667 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
112034114668 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112035114669 } },
112036114670 }, .{
114671 .required_cc_abi = .sysv64,
112037114672 .required_features = .{ .@"64bit", .sse, null, null },
112038114673 .src_constraints = .{ .{ .float = .xword }, .any, .any },
112039114674 .dst_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112062,6 +114697,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112062114697 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
112063114698 } },
112064114699 }, .{
114700 .required_cc_abi = .sysv64,
112065114701 .required_features = .{ .@"64bit", .sse, null, null },
112066114702 .src_constraints = .{ .{ .float = .xword }, .any, .any },
112067114703 .dst_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112090,6 +114726,67 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112090114726 .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
112091114727 } },
112092114728 }, .{
114729 .required_cc_abi = .win64,
114730 .required_features = .{ .@"64bit", null, null, null },
114731 .src_constraints = .{ .{ .float = .xword }, .any, .any },
114732 .dst_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
114733 .patterns = &.{
114734 .{ .src = .{ .to_mem, .none, .none } },
114735 },
114736 .call_frame = .{ .alignment = .@"16" },
114737 .extra_temps = .{
114738 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114739 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
114740 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
114741 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
114742 .unused,
114743 .unused,
114744 .unused,
114745 .unused,
114746 .unused,
114747 .unused,
114748 .unused,
114749 },
114750 .dst_temps = .{ .mem, .unused },
114751 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
114752 .each = .{ .once = &.{
114753 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
114754 .{ ._, ._, .mov, .tmp1d, .sa(.dst0, .add_bit_size), ._, ._ },
114755 .{ ._, ._, .lea, .tmp2p, .mem(.src0), ._, ._ },
114756 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
114757 } },
114758 }, .{
114759 .required_cc_abi = .win64,
114760 .required_features = .{ .@"64bit", null, null, null },
114761 .src_constraints = .{ .{ .float = .xword }, .any, .any },
114762 .dst_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
114763 .patterns = &.{
114764 .{ .src = .{ .to_mem, .none, .none } },
114765 },
114766 .call_frame = .{ .alignment = .@"16" },
114767 .extra_temps = .{
114768 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
114769 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
114770 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
114771 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
114772 .unused,
114773 .unused,
114774 .unused,
114775 .unused,
114776 .unused,
114777 .unused,
114778 .unused,
114779 },
114780 .dst_temps = .{ .mem, .unused },
114781 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
114782 .each = .{ .once = &.{
114783 .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
114784 .{ ._, ._, .mov, .tmp1d, .sa(.dst0, .add_bit_size), ._, ._ },
114785 .{ ._, ._, .lea, .tmp2p, .mem(.src0), ._, ._ },
114786 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
114787 } },
114788 }, .{
114789 .required_cc_abi = .sysv64,
112093114790 .required_features = .{ .@"64bit", .avx, null, null },
112094114791 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112095114792 .dst_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112124,6 +114821,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112124114821 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112125114822 } },
112126114823 }, .{
114824 .required_cc_abi = .sysv64,
112127114825 .required_features = .{ .@"64bit", .avx, null, null },
112128114826 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112129114827 .dst_constraints = .{ .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112158,6 +114856,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112158114856 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112159114857 } },
112160114858 }, .{
114859 .required_cc_abi = .sysv64,
112161114860 .required_features = .{ .@"64bit", .sse2, null, null },
112162114861 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112163114862 .dst_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112192,6 +114891,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112192114891 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112193114892 } },
112194114893 }, .{
114894 .required_cc_abi = .sysv64,
112195114895 .required_features = .{ .@"64bit", .sse2, null, null },
112196114896 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112197114897 .dst_constraints = .{ .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112226,6 +114926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112226114926 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112227114927 } },
112228114928 }, .{
114929 .required_cc_abi = .sysv64,
112229114930 .required_features = .{ .@"64bit", .sse, null, null },
112230114931 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112231114932 .dst_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112260,6 +114961,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112260114961 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112261114962 } },
112262114963 }, .{
114964 .required_cc_abi = .sysv64,
112263114965 .required_features = .{ .@"64bit", .sse, null, null },
112264114966 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
112265114967 .dst_constraints = .{ .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
......@@ -112293,6 +114995,76 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
112293114995 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
112294114996 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
112295114997 } },
114998 }, .{
114999 .required_cc_abi = .win64,
115000 .required_features = .{ .@"64bit", null, null, null },
115001 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
115002 .dst_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any },
115003 .patterns = &.{
115004 .{ .src = .{ .to_mem, .none, .none } },
115005 },
115006 .call_frame = .{ .alignment = .@"16" },
115007 .extra_temps = .{
115008 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
115009 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
115010 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
115011 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
115012 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
115013 .{ .type = .usize, .kind = .{ .extern_func = "__fixtfei" } },
115014 .unused,
115015 .unused,
115016 .unused,
115017 .unused,
115018 .unused,
115019 },
115020 .dst_temps = .{ .mem, .unused },
115021 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
115022 .each = .{ .once = &.{
115023 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
115024 .{ ._, ._, .lea, .tmp1p, .mema(.dst0, .add_unaligned_size_sub_elem_size), ._, ._ },
115025 .{ .@"0:", ._, .mov, .tmp2p, .tmp1p, ._, ._ },
115026 .{ ._, ._, .mov, .tmp3d, .sa(.dst0, .add_bit_size), ._, ._ },
115027 .{ ._, ._, .lea, .tmp4p, .memi(.src0, .tmp0), ._, ._ },
115028 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
115029 .{ ._, ._, .lea, .tmp1p, .leaa(.tmp1, .sub_dst0_elem_size), ._, ._ },
115030 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
115031 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
115032 } },
115033 }, .{
115034 .required_cc_abi = .win64,
115035 .required_features = .{ .@"64bit", null, null, null },
115036 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
115037 .dst_constraints = .{ .{ .scalar_remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, .any },
115038 .patterns = &.{
115039 .{ .src = .{ .to_mem, .none, .none } },
115040 },
115041 .call_frame = .{ .alignment = .@"16" },
115042 .extra_temps = .{
115043 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
115044 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
115045 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
115046 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
115047 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
115048 .{ .type = .usize, .kind = .{ .extern_func = "__fixunstfei" } },
115049 .unused,
115050 .unused,
115051 .unused,
115052 .unused,
115053 .unused,
115054 },
115055 .dst_temps = .{ .mem, .unused },
115056 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
115057 .each = .{ .once = &.{
115058 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
115059 .{ ._, ._, .lea, .tmp1p, .mema(.dst0, .add_unaligned_size_sub_elem_size), ._, ._ },
115060 .{ .@"0:", ._, .mov, .tmp2p, .tmp1p, ._, ._ },
115061 .{ ._, ._, .mov, .tmp3d, .sa(.dst0, .add_bit_size), ._, ._ },
115062 .{ ._, ._, .lea, .tmp4p, .memi(.src0, .tmp0), ._, ._ },
115063 .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
115064 .{ ._, ._, .lea, .tmp1p, .leaa(.tmp1, .sub_dst0_elem_size), ._, ._ },
115065 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
115066 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
115067 } },
112296115068 } }) catch |err| switch (err) {
112297115069 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
112298115070 @tagName(air_tag),
......@@ -139664,6 +142436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
139664142436 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
139665142437 } },
139666142438 }, .{
142439 .required_cc_abi = .sysv64,
139667142440 .required_features = .{ .avx, null, null, null },
139668142441 .dst_constraints = .{ .{ .float = .xword }, .any },
139669142442 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -139695,6 +142468,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
139695142468 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
139696142469 } },
139697142470 }, .{
142471 .required_cc_abi = .sysv64,
139698142472 .required_features = .{ .sse2, null, null, null },
139699142473 .dst_constraints = .{ .{ .float = .xword }, .any },
139700142474 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -139726,6 +142500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
139726142500 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
139727142501 } },
139728142502 }, .{
142503 .required_cc_abi = .sysv64,
139729142504 .required_features = .{ .sse, null, null, null },
139730142505 .dst_constraints = .{ .{ .float = .xword }, .any },
139731142506 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -139756,6 +142531,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
139756142531 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
139757142532 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
139758142533 } },
142534 }, .{
142535 .required_cc_abi = .win64,
142536 .required_features = .{ .avx, null, null, null },
142537 .dst_constraints = .{ .{ .float = .xword }, .any },
142538 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
142539 .patterns = &.{
142540 .{ .src = .{ .to_mem, .none, .none } },
142541 },
142542 .call_frame = .{ .alignment = .@"16" },
142543 .extra_temps = .{
142544 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142545 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142546 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142547 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
142548 .{ .type = .f128, .kind = .mem },
142549 .unused,
142550 .unused,
142551 .unused,
142552 .unused,
142553 .unused,
142554 .unused,
142555 },
142556 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
142557 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
142558 .each = .{ .once = &.{
142559 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
142560 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
142561 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
142562 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
142563 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
142564 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
142565 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
142566 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
142567 } },
142568 }, .{
142569 .required_cc_abi = .win64,
142570 .required_features = .{ .sse2, null, null, null },
142571 .dst_constraints = .{ .{ .float = .xword }, .any },
142572 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
142573 .patterns = &.{
142574 .{ .src = .{ .to_mem, .none, .none } },
142575 },
142576 .call_frame = .{ .alignment = .@"16" },
142577 .extra_temps = .{
142578 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142579 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142580 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142581 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
142582 .{ .type = .f128, .kind = .mem },
142583 .unused,
142584 .unused,
142585 .unused,
142586 .unused,
142587 .unused,
142588 .unused,
142589 },
142590 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
142591 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
142592 .each = .{ .once = &.{
142593 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
142594 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
142595 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
142596 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
142597 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
142598 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
142599 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
142600 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
142601 } },
142602 }, .{
142603 .required_cc_abi = .win64,
142604 .required_features = .{ .sse2, null, null, null },
142605 .dst_constraints = .{ .{ .float = .xword }, .any },
142606 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
142607 .patterns = &.{
142608 .{ .src = .{ .to_mem, .none, .none } },
142609 },
142610 .call_frame = .{ .alignment = .@"16" },
142611 .extra_temps = .{
142612 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
142613 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
142614 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
142615 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
142616 .{ .type = .f128, .kind = .mem },
142617 .unused,
142618 .unused,
142619 .unused,
142620 .unused,
142621 .unused,
142622 .unused,
142623 },
142624 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
142625 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
142626 .each = .{ .once = &.{
142627 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
142628 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
142629 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
142630 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
142631 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
142632 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
142633 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
142634 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
142635 } },
139759142636 } },
139760142637 .Max => comptime &.{ .{
139761142638 .required_features = .{ .avx, null, null, null },
......@@ -149792,6 +152669,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
149792152669 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
149793152670 } },
149794152671 }, .{
152672 .required_cc_abi = .sysv64,
149795152673 .required_features = .{ .avx, null, null, null },
149796152674 .dst_constraints = .{ .{ .float = .xword }, .any },
149797152675 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -149823,6 +152701,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
149823152701 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
149824152702 } },
149825152703 }, .{
152704 .required_cc_abi = .sysv64,
149826152705 .required_features = .{ .sse2, null, null, null },
149827152706 .dst_constraints = .{ .{ .float = .xword }, .any },
149828152707 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -149854,6 +152733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
149854152733 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
149855152734 } },
149856152735 }, .{
152736 .required_cc_abi = .sysv64,
149857152737 .required_features = .{ .sse, null, null, null },
149858152738 .dst_constraints = .{ .{ .float = .xword }, .any },
149859152739 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -149884,6 +152764,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
149884152764 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
149885152765 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
149886152766 } },
152767 }, .{
152768 .required_cc_abi = .win64,
152769 .required_features = .{ .avx, null, null, null },
152770 .dst_constraints = .{ .{ .float = .xword }, .any },
152771 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
152772 .patterns = &.{
152773 .{ .src = .{ .to_mem, .none, .none } },
152774 },
152775 .call_frame = .{ .alignment = .@"16" },
152776 .extra_temps = .{
152777 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152778 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152779 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152780 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
152781 .{ .type = .f128, .kind = .mem },
152782 .unused,
152783 .unused,
152784 .unused,
152785 .unused,
152786 .unused,
152787 .unused,
152788 },
152789 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
152790 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
152791 .each = .{ .once = &.{
152792 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
152793 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
152794 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
152795 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
152796 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
152797 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
152798 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
152799 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
152800 } },
152801 }, .{
152802 .required_cc_abi = .win64,
152803 .required_features = .{ .sse2, null, null, null },
152804 .dst_constraints = .{ .{ .float = .xword }, .any },
152805 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
152806 .patterns = &.{
152807 .{ .src = .{ .to_mem, .none, .none } },
152808 },
152809 .call_frame = .{ .alignment = .@"16" },
152810 .extra_temps = .{
152811 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152812 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152813 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152814 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
152815 .{ .type = .f128, .kind = .mem },
152816 .unused,
152817 .unused,
152818 .unused,
152819 .unused,
152820 .unused,
152821 .unused,
152822 },
152823 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
152824 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
152825 .each = .{ .once = &.{
152826 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
152827 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
152828 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
152829 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
152830 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
152831 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
152832 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
152833 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
152834 } },
152835 }, .{
152836 .required_cc_abi = .win64,
152837 .required_features = .{ .sse2, null, null, null },
152838 .dst_constraints = .{ .{ .float = .xword }, .any },
152839 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
152840 .patterns = &.{
152841 .{ .src = .{ .to_mem, .none, .none } },
152842 },
152843 .call_frame = .{ .alignment = .@"16" },
152844 .extra_temps = .{
152845 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
152846 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
152847 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
152848 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
152849 .{ .type = .f128, .kind = .mem },
152850 .unused,
152851 .unused,
152852 .unused,
152853 .unused,
152854 .unused,
152855 .unused,
152856 },
152857 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
152858 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
152859 .each = .{ .once = &.{
152860 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
152861 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
152862 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
152863 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
152864 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
152865 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
152866 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
152867 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
152868 } },
149887152869 } },
149888152870 .Add => comptime &.{ .{
149889152871 .required_features = .{ .avx, null, null, null },
......@@ -154411,6 +157393,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154411157393 .{ ._, .f_cw, .ld, .tmp1w, ._, ._, ._ },
154412157394 } },
154413157395 }, .{
157396 .required_cc_abi = .sysv64,
154414157397 .required_features = .{ .avx, null, null, null },
154415157398 .dst_constraints = .{ .{ .float = .xword }, .any },
154416157399 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -154442,6 +157425,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154442157425 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
154443157426 } },
154444157427 }, .{
157428 .required_cc_abi = .sysv64,
154445157429 .required_features = .{ .sse2, null, null, null },
154446157430 .dst_constraints = .{ .{ .float = .xword }, .any },
154447157431 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -154473,6 +157457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154473157457 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
154474157458 } },
154475157459 }, .{
157460 .required_cc_abi = .sysv64,
154476157461 .required_features = .{ .sse, null, null, null },
154477157462 .dst_constraints = .{ .{ .float = .xword }, .any },
154478157463 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -154503,6 +157488,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
154503157488 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
154504157489 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
154505157490 } },
157491 }, .{
157492 .required_cc_abi = .win64,
157493 .required_features = .{ .avx, null, null, null },
157494 .dst_constraints = .{ .{ .float = .xword }, .any },
157495 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
157496 .patterns = &.{
157497 .{ .src = .{ .to_mem, .none, .none } },
157498 },
157499 .call_frame = .{ .alignment = .@"16" },
157500 .extra_temps = .{
157501 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
157502 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
157503 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
157504 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157505 .{ .type = .f128, .kind = .mem },
157506 .unused,
157507 .unused,
157508 .unused,
157509 .unused,
157510 .unused,
157511 .unused,
157512 },
157513 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
157514 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
157515 .each = .{ .once = &.{
157516 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
157517 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
157518 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
157519 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
157520 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
157521 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
157522 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
157523 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
157524 } },
157525 }, .{
157526 .required_cc_abi = .win64,
157527 .required_features = .{ .sse2, null, null, null },
157528 .dst_constraints = .{ .{ .float = .xword }, .any },
157529 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
157530 .patterns = &.{
157531 .{ .src = .{ .to_mem, .none, .none } },
157532 },
157533 .call_frame = .{ .alignment = .@"16" },
157534 .extra_temps = .{
157535 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
157536 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
157537 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
157538 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157539 .{ .type = .f128, .kind = .mem },
157540 .unused,
157541 .unused,
157542 .unused,
157543 .unused,
157544 .unused,
157545 .unused,
157546 },
157547 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
157548 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
157549 .each = .{ .once = &.{
157550 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
157551 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
157552 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
157553 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
157554 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
157555 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
157556 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
157557 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
157558 } },
157559 }, .{
157560 .required_cc_abi = .win64,
157561 .required_features = .{ .sse, null, null, null },
157562 .dst_constraints = .{ .{ .float = .xword }, .any },
157563 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
157564 .patterns = &.{
157565 .{ .src = .{ .to_mem, .none, .none } },
157566 },
157567 .call_frame = .{ .alignment = .@"16" },
157568 .extra_temps = .{
157569 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
157570 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
157571 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
157572 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
157573 .{ .type = .f128, .kind = .mem },
157574 .unused,
157575 .unused,
157576 .unused,
157577 .unused,
157578 .unused,
157579 .unused,
157580 },
157581 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
157582 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
157583 .each = .{ .once = &.{
157584 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
157585 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
157586 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
157587 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
157588 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
157589 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
157590 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
157591 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
157592 } },
154506157593 } },
154507157594 .Mul => comptime &.{ .{
154508157595 .required_features = .{ .avx, null, null, null },
......@@ -157989,6 +161076,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
157989161076 .{ ._, .f_cw, .ld, .tmp1w, ._, ._, ._ },
157990161077 } },
157991161078 }, .{
161079 .required_cc_abi = .sysv64,
157992161080 .required_features = .{ .avx, null, null, null },
157993161081 .dst_constraints = .{ .{ .float = .xword }, .any },
157994161082 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -158020,6 +161108,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158020161108 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
158021161109 } },
158022161110 }, .{
161111 .required_cc_abi = .sysv64,
158023161112 .required_features = .{ .sse2, null, null, null },
158024161113 .dst_constraints = .{ .{ .float = .xword }, .any },
158025161114 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -158051,6 +161140,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158051161140 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
158052161141 } },
158053161142 }, .{
161143 .required_cc_abi = .sysv64,
158054161144 .required_features = .{ .sse, null, null, null },
158055161145 .dst_constraints = .{ .{ .float = .xword }, .any },
158056161146 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -158081,6 +161171,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
158081161171 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
158082161172 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
158083161173 } },
161174 }, .{
161175 .required_cc_abi = .win64,
161176 .required_features = .{ .avx, null, null, null },
161177 .dst_constraints = .{ .{ .float = .xword }, .any },
161178 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
161179 .patterns = &.{
161180 .{ .src = .{ .to_mem, .none, .none } },
161181 },
161182 .call_frame = .{ .alignment = .@"16" },
161183 .extra_temps = .{
161184 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
161185 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
161186 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
161187 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
161188 .{ .type = .f128, .kind = .mem },
161189 .unused,
161190 .unused,
161191 .unused,
161192 .unused,
161193 .unused,
161194 .unused,
161195 },
161196 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
161197 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
161198 .each = .{ .once = &.{
161199 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
161200 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
161201 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
161202 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
161203 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
161204 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
161205 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
161206 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
161207 } },
161208 }, .{
161209 .required_cc_abi = .win64,
161210 .required_features = .{ .sse2, null, null, null },
161211 .dst_constraints = .{ .{ .float = .xword }, .any },
161212 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
161213 .patterns = &.{
161214 .{ .src = .{ .to_mem, .none, .none } },
161215 },
161216 .call_frame = .{ .alignment = .@"16" },
161217 .extra_temps = .{
161218 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
161219 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
161220 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
161221 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
161222 .{ .type = .f128, .kind = .mem },
161223 .unused,
161224 .unused,
161225 .unused,
161226 .unused,
161227 .unused,
161228 .unused,
161229 },
161230 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
161231 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
161232 .each = .{ .once = &.{
161233 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
161234 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
161235 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
161236 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
161237 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
161238 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
161239 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
161240 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
161241 } },
161242 }, .{
161243 .required_cc_abi = .win64,
161244 .required_features = .{ .sse, null, null, null },
161245 .dst_constraints = .{ .{ .float = .xword }, .any },
161246 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
161247 .patterns = &.{
161248 .{ .src = .{ .to_mem, .none, .none } },
161249 },
161250 .call_frame = .{ .alignment = .@"16" },
161251 .extra_temps = .{
161252 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
161253 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
161254 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
161255 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
161256 .{ .type = .f128, .kind = .mem },
161257 .unused,
161258 .unused,
161259 .unused,
161260 .unused,
161261 .unused,
161262 .unused,
161263 },
161264 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
161265 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
161266 .each = .{ .once = &.{
161267 .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_unaligned_size), ._, ._ },
161268 .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
161269 .{ .@"0:", ._, .lea, .tmp2p, .memia(.src0, .tmp0, .add_unaligned_size), ._, ._ },
161270 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
161271 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
161272 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
161273 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
161274 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
161275 } },
158084161276 } },
158085161277 }) catch |err| switch (err) {
158086161278 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{
......@@ -159711,6 +162903,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159711162903 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
159712162904 } },
159713162905 }, .{
162906 .required_cc_abi = .sysv64,
159714162907 .required_features = .{ .avx, null, null, null },
159715162908 .dst_constraints = .{ .{ .float = .xword }, .any },
159716162909 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -159742,6 +162935,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159742162935 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
159743162936 } },
159744162937 }, .{
162938 .required_cc_abi = .sysv64,
159745162939 .required_features = .{ .sse2, null, null, null },
159746162940 .dst_constraints = .{ .{ .float = .xword }, .any },
159747162941 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -159773,6 +162967,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159773162967 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
159774162968 } },
159775162969 }, .{
162970 .required_cc_abi = .sysv64,
159776162971 .required_features = .{ .sse, null, null, null },
159777162972 .dst_constraints = .{ .{ .float = .xword }, .any },
159778162973 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -159803,6 +162998,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
159803162998 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
159804162999 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
159805163000 } },
163001 }, .{
163002 .required_cc_abi = .win64,
163003 .required_features = .{ .avx, null, null, null },
163004 .dst_constraints = .{ .{ .float = .xword }, .any },
163005 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
163006 .patterns = &.{
163007 .{ .src = .{ .to_mem, .none, .none } },
163008 },
163009 .call_frame = .{ .alignment = .@"16" },
163010 .extra_temps = .{
163011 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163012 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163013 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163014 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
163015 .{ .type = .f128, .kind = .mem },
163016 .unused,
163017 .unused,
163018 .unused,
163019 .unused,
163020 .unused,
163021 .unused,
163022 },
163023 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
163024 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
163025 .each = .{ .once = &.{
163026 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
163027 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
163028 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
163029 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
163030 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
163031 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
163032 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
163033 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163034 } },
163035 }, .{
163036 .required_cc_abi = .win64,
163037 .required_features = .{ .sse2, null, null, null },
163038 .dst_constraints = .{ .{ .float = .xword }, .any },
163039 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
163040 .patterns = &.{
163041 .{ .src = .{ .to_mem, .none, .none } },
163042 },
163043 .call_frame = .{ .alignment = .@"16" },
163044 .extra_temps = .{
163045 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163046 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163047 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163048 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
163049 .{ .type = .f128, .kind = .mem },
163050 .unused,
163051 .unused,
163052 .unused,
163053 .unused,
163054 .unused,
163055 .unused,
163056 },
163057 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
163058 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
163059 .each = .{ .once = &.{
163060 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
163061 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
163062 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
163063 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
163064 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
163065 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
163066 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
163067 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163068 } },
163069 }, .{
163070 .required_cc_abi = .win64,
163071 .required_features = .{ .sse2, null, null, null },
163072 .dst_constraints = .{ .{ .float = .xword }, .any },
163073 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
163074 .patterns = &.{
163075 .{ .src = .{ .to_mem, .none, .none } },
163076 },
163077 .call_frame = .{ .alignment = .@"16" },
163078 .extra_temps = .{
163079 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
163080 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
163081 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
163082 .{ .type = .usize, .kind = .{ .extern_func = "fminq" } },
163083 .{ .type = .f128, .kind = .mem },
163084 .unused,
163085 .unused,
163086 .unused,
163087 .unused,
163088 .unused,
163089 .unused,
163090 },
163091 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
163092 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
163093 .each = .{ .once = &.{
163094 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
163095 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
163096 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
163097 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
163098 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
163099 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
163100 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
163101 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163102 } },
159806163103 } },
159807163104 .Max => comptime &.{ .{
159808163105 .required_features = .{ .f16c, null, null, null },
......@@ -161403,6 +164700,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161403164700 .{ ._, .f_p, .st, .dst0t, ._, ._, ._ },
161404164701 } },
161405164702 }, .{
164703 .required_cc_abi = .sysv64,
161406164704 .required_features = .{ .avx, null, null, null },
161407164705 .dst_constraints = .{ .{ .float = .xword }, .any },
161408164706 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -161434,6 +164732,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161434164732 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
161435164733 } },
161436164734 }, .{
164735 .required_cc_abi = .sysv64,
161437164736 .required_features = .{ .sse2, null, null, null },
161438164737 .dst_constraints = .{ .{ .float = .xword }, .any },
161439164738 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -161465,6 +164764,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161465164764 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
161466164765 } },
161467164766 }, .{
164767 .required_cc_abi = .sysv64,
161468164768 .required_features = .{ .sse, null, null, null },
161469164769 .dst_constraints = .{ .{ .float = .xword }, .any },
161470164770 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -161495,6 +164795,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161495164795 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
161496164796 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
161497164797 } },
164798 }, .{
164799 .required_cc_abi = .win64,
164800 .required_features = .{ .avx, null, null, null },
164801 .dst_constraints = .{ .{ .float = .xword }, .any },
164802 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
164803 .patterns = &.{
164804 .{ .src = .{ .to_mem, .none, .none } },
164805 },
164806 .call_frame = .{ .alignment = .@"16" },
164807 .extra_temps = .{
164808 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164809 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164810 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164811 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
164812 .{ .type = .f128, .kind = .mem },
164813 .unused,
164814 .unused,
164815 .unused,
164816 .unused,
164817 .unused,
164818 .unused,
164819 },
164820 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
164821 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
164822 .each = .{ .once = &.{
164823 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
164824 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
164825 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
164826 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
164827 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
164828 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
164829 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
164830 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
164831 } },
164832 }, .{
164833 .required_cc_abi = .win64,
164834 .required_features = .{ .sse2, null, null, null },
164835 .dst_constraints = .{ .{ .float = .xword }, .any },
164836 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
164837 .patterns = &.{
164838 .{ .src = .{ .to_mem, .none, .none } },
164839 },
164840 .call_frame = .{ .alignment = .@"16" },
164841 .extra_temps = .{
164842 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164843 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164844 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164845 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
164846 .{ .type = .f128, .kind = .mem },
164847 .unused,
164848 .unused,
164849 .unused,
164850 .unused,
164851 .unused,
164852 .unused,
164853 },
164854 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
164855 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
164856 .each = .{ .once = &.{
164857 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
164858 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
164859 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
164860 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
164861 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
164862 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
164863 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
164864 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
164865 } },
164866 }, .{
164867 .required_cc_abi = .win64,
164868 .required_features = .{ .sse2, null, null, null },
164869 .dst_constraints = .{ .{ .float = .xword }, .any },
164870 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
164871 .patterns = &.{
164872 .{ .src = .{ .to_mem, .none, .none } },
164873 },
164874 .call_frame = .{ .alignment = .@"16" },
164875 .extra_temps = .{
164876 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
164877 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
164878 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
164879 .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } },
164880 .{ .type = .f128, .kind = .mem },
164881 .unused,
164882 .unused,
164883 .unused,
164884 .unused,
164885 .unused,
164886 .unused,
164887 },
164888 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
164889 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
164890 .each = .{ .once = &.{
164891 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
164892 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
164893 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
164894 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
164895 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
164896 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
164897 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
164898 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
164899 } },
161498164900 } },
161499164901 .Add => comptime &.{ .{
161500164902 .required_features = .{ .f16c, .fast_hops, null, null },
......@@ -163701,6 +167103,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163701167103 .{ ._, .f_cw, .ld, .tmp1w, ._, ._, ._ },
163702167104 } },
163703167105 }, .{
167106 .required_cc_abi = .sysv64,
163704167107 .required_features = .{ .avx, null, null, null },
163705167108 .dst_constraints = .{ .{ .float = .xword }, .any },
163706167109 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -163732,6 +167135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163732167135 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163733167136 } },
163734167137 }, .{
167138 .required_cc_abi = .sysv64,
163735167139 .required_features = .{ .sse2, null, null, null },
163736167140 .dst_constraints = .{ .{ .float = .xword }, .any },
163737167141 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -163763,6 +167167,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163763167167 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163764167168 } },
163765167169 }, .{
167170 .required_cc_abi = .sysv64,
163766167171 .required_features = .{ .sse, null, null, null },
163767167172 .dst_constraints = .{ .{ .float = .xword }, .any },
163768167173 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -163793,6 +167198,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
163793167198 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
163794167199 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
163795167200 } },
167201 }, .{
167202 .required_cc_abi = .win64,
167203 .required_features = .{ .avx, null, null, null },
167204 .dst_constraints = .{ .{ .float = .xword }, .any },
167205 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
167206 .patterns = &.{
167207 .{ .src = .{ .to_mem, .none, .none } },
167208 },
167209 .call_frame = .{ .alignment = .@"16" },
167210 .extra_temps = .{
167211 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
167212 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
167213 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
167214 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
167215 .{ .type = .f128, .kind = .mem },
167216 .unused,
167217 .unused,
167218 .unused,
167219 .unused,
167220 .unused,
167221 .unused,
167222 },
167223 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
167224 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
167225 .each = .{ .once = &.{
167226 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
167227 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
167228 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
167229 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
167230 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
167231 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
167232 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
167233 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
167234 } },
167235 }, .{
167236 .required_cc_abi = .win64,
167237 .required_features = .{ .sse2, null, null, null },
167238 .dst_constraints = .{ .{ .float = .xword }, .any },
167239 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
167240 .patterns = &.{
167241 .{ .src = .{ .to_mem, .none, .none } },
167242 },
167243 .call_frame = .{ .alignment = .@"16" },
167244 .extra_temps = .{
167245 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
167246 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
167247 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
167248 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
167249 .{ .type = .f128, .kind = .mem },
167250 .unused,
167251 .unused,
167252 .unused,
167253 .unused,
167254 .unused,
167255 .unused,
167256 },
167257 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
167258 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
167259 .each = .{ .once = &.{
167260 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
167261 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
167262 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
167263 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
167264 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
167265 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
167266 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
167267 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
167268 } },
167269 }, .{
167270 .required_cc_abi = .win64,
167271 .required_features = .{ .sse, null, null, null },
167272 .dst_constraints = .{ .{ .float = .xword }, .any },
167273 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
167274 .patterns = &.{
167275 .{ .src = .{ .to_mem, .none, .none } },
167276 },
167277 .call_frame = .{ .alignment = .@"16" },
167278 .extra_temps = .{
167279 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
167280 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
167281 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
167282 .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } },
167283 .{ .type = .f128, .kind = .mem },
167284 .unused,
167285 .unused,
167286 .unused,
167287 .unused,
167288 .unused,
167289 .unused,
167290 },
167291 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
167292 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
167293 .each = .{ .once = &.{
167294 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
167295 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
167296 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
167297 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
167298 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
167299 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
167300 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
167301 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
167302 } },
163796167303 } },
163797167304 .Mul => comptime &.{ .{
163798167305 .required_features = .{ .f16c, null, null, null },
......@@ -165283,6 +168790,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
165283168790 .{ ._, .f_cw, .ld, .tmp1w, ._, ._, ._ },
165284168791 } },
165285168792 }, .{
168793 .required_cc_abi = .sysv64,
165286168794 .required_features = .{ .avx, null, null, null },
165287168795 .dst_constraints = .{ .{ .float = .xword }, .any },
165288168796 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -165314,6 +168822,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
165314168822 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
165315168823 } },
165316168824 }, .{
168825 .required_cc_abi = .sysv64,
165317168826 .required_features = .{ .sse2, null, null, null },
165318168827 .dst_constraints = .{ .{ .float = .xword }, .any },
165319168828 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -165345,6 +168854,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
165345168854 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
165346168855 } },
165347168856 }, .{
168857 .required_cc_abi = .sysv64,
165348168858 .required_features = .{ .sse, null, null, null },
165349168859 .dst_constraints = .{ .{ .float = .xword }, .any },
165350168860 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
......@@ -165375,6 +168885,108 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
165375168885 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
165376168886 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
165377168887 } },
168888 }, .{
168889 .required_cc_abi = .win64,
168890 .required_features = .{ .avx, null, null, null },
168891 .dst_constraints = .{ .{ .float = .xword }, .any },
168892 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
168893 .patterns = &.{
168894 .{ .src = .{ .to_mem, .none, .none } },
168895 },
168896 .call_frame = .{ .alignment = .@"16" },
168897 .extra_temps = .{
168898 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
168899 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
168900 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
168901 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
168902 .{ .type = .f128, .kind = .mem },
168903 .unused,
168904 .unused,
168905 .unused,
168906 .unused,
168907 .unused,
168908 .unused,
168909 },
168910 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
168911 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
168912 .each = .{ .once = &.{
168913 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
168914 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
168915 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
168916 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
168917 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
168918 .{ ._, .v_dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
168919 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
168920 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
168921 } },
168922 }, .{
168923 .required_cc_abi = .win64,
168924 .required_features = .{ .sse2, null, null, null },
168925 .dst_constraints = .{ .{ .float = .xword }, .any },
168926 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
168927 .patterns = &.{
168928 .{ .src = .{ .to_mem, .none, .none } },
168929 },
168930 .call_frame = .{ .alignment = .@"16" },
168931 .extra_temps = .{
168932 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
168933 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
168934 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
168935 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
168936 .{ .type = .f128, .kind = .mem },
168937 .unused,
168938 .unused,
168939 .unused,
168940 .unused,
168941 .unused,
168942 .unused,
168943 },
168944 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
168945 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
168946 .each = .{ .once = &.{
168947 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
168948 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
168949 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
168950 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
168951 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
168952 .{ ._, ._dqa, .mov, .lea(.tmp1x), .dst0x, ._, ._ },
168953 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
168954 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
168955 } },
168956 }, .{
168957 .required_cc_abi = .win64,
168958 .required_features = .{ .sse, null, null, null },
168959 .dst_constraints = .{ .{ .float = .xword }, .any },
168960 .src_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any, .any },
168961 .patterns = &.{
168962 .{ .src = .{ .to_mem, .none, .none } },
168963 },
168964 .call_frame = .{ .alignment = .@"16" },
168965 .extra_temps = .{
168966 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
168967 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
168968 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
168969 .{ .type = .usize, .kind = .{ .extern_func = "__multf3" } },
168970 .{ .type = .f128, .kind = .mem },
168971 .unused,
168972 .unused,
168973 .unused,
168974 .unused,
168975 .unused,
168976 .unused,
168977 },
168978 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
168979 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
168980 .each = .{ .once = &.{
168981 .{ ._, ._, .mov, .tmp0d, .sia(-32, .src0, .add_unaligned_size), ._, ._ },
168982 .{ ._, ._, .lea, .tmp1p, .memad(.src0, .add_unaligned_size, -16), ._, ._ },
168983 .{ .@"0:", ._, .lea, .tmp2p, .memi(.src0, .tmp0), ._, ._ },
168984 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
168985 .{ ._, ._, .lea, .tmp1p, .mem(.tmp4), ._, ._ },
168986 .{ ._, ._ps, .mova, .lea(.tmp1x), .dst0x, ._, ._ },
168987 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
168988 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
168989 } },
165378168990 } },
165379168991 }) catch |err| switch (err) {
165380168992 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{
......@@ -169007,6 +172619,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169007172619 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
169008172620 } },
169009172621 }, .{
172622 .required_cc_abi = .sysv64,
169010172623 .required_features = .{ .sse, null, null, null },
169011172624 .src_constraints = .{
169012172625 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -169040,6 +172653,40 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169040172653 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
169041172654 } },
169042172655 }, .{
172656 .required_cc_abi = .win64,
172657 .required_features = .{ .sse, null, null, null },
172658 .src_constraints = .{
172659 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
172660 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
172661 .{ .scalar_float = .{ .of = .xword, .is = .xword } },
172662 },
172663 .patterns = &.{
172664 .{ .src = .{ .to_mem, .to_mem, .to_mem } },
172665 },
172666 .call_frame = .{ .alignment = .@"16" },
172667 .extra_temps = .{
172668 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172669 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172670 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172671 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
172672 .unused,
172673 .unused,
172674 .unused,
172675 .unused,
172676 .unused,
172677 .unused,
172678 .unused,
172679 },
172680 .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused },
172681 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
172682 .each = .{ .once = &.{
172683 .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ },
172684 .{ ._, ._, .lea, .tmp1p, .mem(.src1), ._, ._ },
172685 .{ ._, ._, .lea, .tmp2p, .mem(.src2), ._, ._ },
172686 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
172687 } },
172688 }, .{
172689 .required_cc_abi = .sysv64,
169043172690 .required_features = .{ .avx, null, null, null },
169044172691 .src_constraints = .{
169045172692 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -169076,6 +172723,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169076172723 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
169077172724 } },
169078172725 }, .{
172726 .required_cc_abi = .sysv64,
169079172727 .required_features = .{ .sse2, null, null, null },
169080172728 .src_constraints = .{
169081172729 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -169112,6 +172760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169112172760 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
169113172761 } },
169114172762 }, .{
172763 .required_cc_abi = .sysv64,
169115172764 .required_features = .{ .sse, null, null, null },
169116172765 .src_constraints = .{
169117172766 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
......@@ -169147,6 +172796,117 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169147172796 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
169148172797 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
169149172798 } },
172799 }, .{
172800 .required_cc_abi = .win64,
172801 .required_features = .{ .avx, null, null, null },
172802 .src_constraints = .{
172803 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172804 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172805 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172806 },
172807 .patterns = &.{
172808 .{ .src = .{ .to_mem, .to_mem, .to_mem } },
172809 },
172810 .call_frame = .{ .alignment = .@"16" },
172811 .extra_temps = .{
172812 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
172813 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172814 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172815 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172816 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
172817 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172818 .unused,
172819 .unused,
172820 .unused,
172821 .unused,
172822 .unused,
172823 },
172824 .dst_temps = .{ .mem, .unused },
172825 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
172826 .each = .{ .once = &.{
172827 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
172828 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
172829 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
172830 .{ ._, ._, .lea, .tmp3p, .memi(.src2, .tmp0), ._, ._ },
172831 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
172832 .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
172833 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
172834 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
172835 } },
172836 }, .{
172837 .required_cc_abi = .win64,
172838 .required_features = .{ .sse2, null, null, null },
172839 .src_constraints = .{
172840 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172841 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172842 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172843 },
172844 .patterns = &.{
172845 .{ .src = .{ .to_mem, .to_mem, .to_mem } },
172846 },
172847 .call_frame = .{ .alignment = .@"16" },
172848 .extra_temps = .{
172849 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
172850 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172851 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172852 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172853 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
172854 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172855 .unused,
172856 .unused,
172857 .unused,
172858 .unused,
172859 .unused,
172860 },
172861 .dst_temps = .{ .mem, .unused },
172862 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
172863 .each = .{ .once = &.{
172864 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
172865 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
172866 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
172867 .{ ._, ._, .lea, .tmp3p, .memi(.src2, .tmp0), ._, ._ },
172868 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
172869 .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
172870 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
172871 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
172872 } },
172873 }, .{
172874 .required_cc_abi = .win64,
172875 .required_features = .{ .sse, null, null, null },
172876 .src_constraints = .{
172877 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172878 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172879 .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } },
172880 },
172881 .patterns = &.{
172882 .{ .src = .{ .to_mem, .to_mem, .to_mem } },
172883 },
172884 .call_frame = .{ .alignment = .@"16" },
172885 .extra_temps = .{
172886 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
172887 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172888 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } },
172889 .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } },
172890 .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } },
172891 .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } },
172892 .unused,
172893 .unused,
172894 .unused,
172895 .unused,
172896 .unused,
172897 },
172898 .dst_temps = .{ .mem, .unused },
172899 .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
172900 .each = .{ .once = &.{
172901 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ },
172902 .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ },
172903 .{ ._, ._, .lea, .tmp2p, .memi(.src1, .tmp0), ._, ._ },
172904 .{ ._, ._, .lea, .tmp3p, .memi(.src2, .tmp0), ._, ._ },
172905 .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
172906 .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp5x, ._, ._ },
172907 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
172908 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
172909 } },
169150172910 } }) catch |err| switch (err) {
169151172911 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
169152172912 @tagName(air_tag),
......@@ -170541,4887 +174301,78 @@ fn copyToRegisterWithInstTracking(
170541174301 return MCValue{ .register = reg };
170542174302}
170543174303
170544fn airAlloc(self: *CodeGen, inst: Air.Inst.Index) !void {
170545 const result = MCValue{ .lea_frame = .{ .index = try self.allocMemPtr(inst) } };
170546 return self.finishAir(inst, result, .{ .none, .none, .none });
170547}
170548
170549fn airRetPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
170550 const result: MCValue = switch (self.ret_mcv.long) {
170551 else => unreachable,
170552 .none => .{ .lea_frame = .{ .index = try self.allocMemPtr(inst) } },
170553 .load_frame => .{ .register_offset = .{
170554 .reg = (try self.copyToRegisterWithInstTracking(
170555 inst,
170556 self.typeOfIndex(inst),
170557 self.ret_mcv.long,
170558 )).register,
170559 .off = self.ret_mcv.short.indirect.off,
170560 } },
170561 };
170562 return self.finishAir(inst, result, .{ .none, .none, .none });
170563}
170564
170565fn airFptrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
170566 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
170567 const dst_ty = self.typeOfIndex(inst);
170568 const dst_bits = dst_ty.floatBits(self.target);
170569 const src_ty = self.typeOf(ty_op.operand);
170570 const src_bits = src_ty.floatBits(self.target);
170571
170572 const result = result: {
170573 if (switch (dst_bits) {
170574 16 => switch (src_bits) {
170575 32 => !self.hasFeature(.f16c),
170576 64, 80, 128 => true,
170577 else => unreachable,
170578 },
170579 32 => switch (src_bits) {
170580 64 => false,
170581 80, 128 => true,
170582 else => unreachable,
170583 },
170584 64 => switch (src_bits) {
170585 80, 128 => true,
170586 else => unreachable,
170587 },
170588 80 => switch (src_bits) {
170589 128 => true,
170590 else => unreachable,
170591 },
170592 else => unreachable,
170593 }) {
170594 var sym_buf: ["__trunc?f?f2".len]u8 = undefined;
170595 break :result try self.genCall(.{ .extern_func = .{
170596 .return_type = self.floatCompilerRtAbiType(dst_ty, src_ty).toIntern(),
170597 .param_types = &.{self.floatCompilerRtAbiType(src_ty, dst_ty).toIntern()},
170598 .sym = std.fmt.bufPrint(&sym_buf, "__trunc{c}f{c}f2", .{
170599 floatCompilerRtAbiName(src_bits),
170600 floatCompilerRtAbiName(dst_bits),
170601 }) catch unreachable,
170602 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
170603 }
170604
170605 const src_mcv = try self.resolveInst(ty_op.operand);
170606 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170607 src_mcv
170608 else
170609 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
170610 const dst_reg = dst_mcv.getReg().?.to128();
170611 const dst_lock = self.register_manager.lockReg(dst_reg);
170612 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
170613
170614 if (dst_bits == 16) {
170615 assert(self.hasFeature(.f16c));
170616 switch (src_bits) {
170617 32 => {
170618 const mat_src_reg = if (src_mcv.isRegister())
170619 src_mcv.getReg().?
170620 else
170621 try self.copyToTmpRegister(src_ty, src_mcv);
170622 try self.asmRegisterRegisterImmediate(
170623 .{ .v_, .cvtps2ph },
170624 dst_reg,
170625 mat_src_reg.to128(),
170626 bits.RoundMode.imm(.{}),
170627 );
170628 },
170629 else => unreachable,
170630 }
170631 } else {
170632 assert(src_bits == 64 and dst_bits == 32);
170633 if (self.hasFeature(.avx)) if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
170634 .{ .v_ss, .cvtsd2 },
170635 dst_reg,
170636 dst_reg,
170637 try src_mcv.mem(self, .{ .size = .qword }),
170638 ) else try self.asmRegisterRegisterRegister(
170639 .{ .v_ss, .cvtsd2 },
170640 dst_reg,
170641 dst_reg,
170642 (if (src_mcv.isRegister())
170643 src_mcv.getReg().?
170644 else
170645 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
170646 ) else if (src_mcv.isBase()) try self.asmRegisterMemory(
170647 .{ ._ss, .cvtsd2 },
170648 dst_reg,
170649 try src_mcv.mem(self, .{ .size = .qword }),
170650 ) else try self.asmRegisterRegister(
170651 .{ ._ss, .cvtsd2 },
170652 dst_reg,
170653 (if (src_mcv.isRegister())
170654 src_mcv.getReg().?
170655 else
170656 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
170657 );
170658 }
170659 break :result dst_mcv;
170660 };
170661 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
170662}
170663
170664fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void {
170665 const pt = self.pt;
170666 const zcu = pt.zcu;
170667 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
170668 const dst_ty = self.typeOfIndex(inst);
170669 const dst_scalar_ty = dst_ty.scalarType(zcu);
170670 const dst_bits = dst_scalar_ty.floatBits(self.target);
170671 const src_ty = self.typeOf(ty_op.operand);
170672 const src_scalar_ty = src_ty.scalarType(zcu);
170673 const src_bits = src_scalar_ty.floatBits(self.target);
170674
170675 const result = result: {
170676 if (switch (src_bits) {
170677 16 => switch (dst_bits) {
170678 32, 64 => !self.hasFeature(.f16c),
170679 80, 128 => true,
170680 else => unreachable,
170681 },
170682 32 => switch (dst_bits) {
170683 64 => false,
170684 80, 128 => true,
170685 else => unreachable,
170686 },
170687 64 => switch (dst_bits) {
170688 80, 128 => true,
170689 else => unreachable,
170690 },
170691 80 => switch (dst_bits) {
170692 128 => true,
170693 else => unreachable,
170694 },
170695 else => unreachable,
170696 }) {
170697 if (dst_ty.isVector(zcu)) break :result null;
170698 var sym_buf: ["__extend?f?f2".len]u8 = undefined;
170699 break :result try self.genCall(.{ .extern_func = .{
170700 .return_type = self.floatCompilerRtAbiType(dst_scalar_ty, src_scalar_ty).toIntern(),
170701 .param_types = &.{self.floatCompilerRtAbiType(src_scalar_ty, dst_scalar_ty).toIntern()},
170702 .sym = std.fmt.bufPrint(&sym_buf, "__extend{c}f{c}f2", .{
170703 floatCompilerRtAbiName(src_bits),
170704 floatCompilerRtAbiName(dst_bits),
170705 }) catch unreachable,
170706 } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
170707 }
170708
170709 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
170710 const src_mcv = try self.resolveInst(ty_op.operand);
170711 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170712 src_mcv
170713 else
170714 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
170715 const dst_reg = dst_mcv.getReg().?;
170716 const dst_alias = registerAlias(dst_reg, @intCast(@max(dst_ty.abiSize(zcu), 16)));
170717 const dst_lock = self.register_manager.lockReg(dst_reg);
170718 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
170719
170720 const vec_len = if (dst_ty.isVector(zcu)) dst_ty.vectorLen(zcu) else 1;
170721 if (src_bits == 16) {
170722 assert(self.hasFeature(.f16c));
170723 const mat_src_reg = if (src_mcv.isRegister())
170724 src_mcv.getReg().?
170725 else
170726 try self.copyToTmpRegister(src_ty, src_mcv);
170727 try self.asmRegisterRegister(
170728 .{ .v_ps, .cvtph2 },
170729 dst_alias,
170730 registerAlias(mat_src_reg, src_abi_size),
170731 );
170732 switch (dst_bits) {
170733 32 => {},
170734 64 => try self.asmRegisterRegisterRegister(
170735 .{ .v_sd, .cvtss2 },
170736 dst_alias,
170737 dst_alias,
170738 dst_alias,
170739 ),
170740 else => unreachable,
170741 }
170742 } else {
170743 assert(src_bits == 32 and dst_bits == 64);
170744 if (self.hasFeature(.avx)) switch (vec_len) {
170745 1 => if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
170746 .{ .v_sd, .cvtss2 },
170747 dst_alias,
170748 dst_alias,
170749 try src_mcv.mem(self, .{ .size = self.memSize(src_ty) }),
170750 ) else try self.asmRegisterRegisterRegister(
170751 .{ .v_sd, .cvtss2 },
170752 dst_alias,
170753 dst_alias,
170754 registerAlias(if (src_mcv.isRegister())
170755 src_mcv.getReg().?
170756 else
170757 try self.copyToTmpRegister(src_ty, src_mcv), src_abi_size),
170758 ),
170759 2...4 => if (src_mcv.isBase()) try self.asmRegisterMemory(
170760 .{ .v_pd, .cvtps2 },
170761 dst_alias,
170762 try src_mcv.mem(self, .{ .size = self.memSize(src_ty) }),
170763 ) else try self.asmRegisterRegister(
170764 .{ .v_pd, .cvtps2 },
170765 dst_alias,
170766 registerAlias(if (src_mcv.isRegister())
170767 src_mcv.getReg().?
170768 else
170769 try self.copyToTmpRegister(src_ty, src_mcv), src_abi_size),
170770 ),
170771 else => break :result null,
170772 } else if (src_mcv.isBase()) try self.asmRegisterMemory(
170773 switch (vec_len) {
170774 1 => .{ ._sd, .cvtss2 },
170775 2 => .{ ._pd, .cvtps2 },
170776 else => break :result null,
170777 },
170778 dst_alias,
170779 try src_mcv.mem(self, .{ .size = self.memSize(src_ty) }),
170780 ) else try self.asmRegisterRegister(
170781 switch (vec_len) {
170782 1 => .{ ._sd, .cvtss2 },
170783 2 => .{ ._pd, .cvtps2 },
170784 else => break :result null,
170785 },
170786 dst_alias,
170787 registerAlias(if (src_mcv.isRegister())
170788 src_mcv.getReg().?
170789 else
170790 try self.copyToTmpRegister(src_ty, src_mcv), src_abi_size),
170791 );
170792 }
170793 break :result dst_mcv;
170794 } orelse return self.fail("TODO implement airFpext from {f} to {f}", .{
170795 src_ty.fmt(pt), dst_ty.fmt(pt),
170796 });
170797 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
170798}
170799
170800fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {
170801 const pt = self.pt;
170802 const zcu = pt.zcu;
170803 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
170804 const src_ty = self.typeOf(ty_op.operand);
170805 const dst_ty = self.typeOfIndex(inst);
170806
170807 const result = @as(?MCValue, result: {
170808 const src_abi_size: u31 = @intCast(src_ty.abiSize(zcu));
170809 const dst_abi_size: u31 = @intCast(dst_ty.abiSize(zcu));
170810
170811 const src_int_info = src_ty.intInfo(zcu);
170812 const dst_int_info = dst_ty.intInfo(zcu);
170813 const extend = switch (src_int_info.signedness) {
170814 .signed => dst_int_info,
170815 .unsigned => src_int_info,
170816 }.signedness;
170817
170818 const src_mcv = try self.resolveInst(ty_op.operand);
170819 if (dst_ty.isVector(zcu)) {
170820 const max_abi_size = @max(dst_abi_size, src_abi_size);
170821 const has_avx = self.hasFeature(.avx);
170822
170823 const dst_elem_abi_size = dst_ty.childType(zcu).abiSize(zcu);
170824 const src_elem_abi_size = src_ty.childType(zcu).abiSize(zcu);
170825 switch (std.math.order(dst_elem_abi_size, src_elem_abi_size)) {
170826 .lt => {
170827 if (max_abi_size > self.vectorSize(.int)) break :result null;
170828 const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) {
170829 else => break :result null,
170830 1 => switch (src_elem_abi_size) {
170831 else => break :result null,
170832 2 => switch (dst_int_info.signedness) {
170833 .signed => if (has_avx) .{ .vp_b, .ackssw } else .{ .p_b, .ackssw },
170834 .unsigned => if (has_avx) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw },
170835 },
170836 },
170837 2 => switch (src_elem_abi_size) {
170838 else => break :result null,
170839 4 => switch (dst_int_info.signedness) {
170840 .signed => if (has_avx) .{ .vp_w, .ackssd } else .{ .p_w, .ackssd },
170841 .unsigned => if (has_avx)
170842 .{ .vp_w, .ackusd }
170843 else if (self.hasFeature(.sse4_1))
170844 .{ .p_w, .ackusd }
170845 else
170846 break :result null,
170847 },
170848 },
170849 };
170850
170851 const dst_mcv: MCValue = if (src_mcv.isRegister() and
170852 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170853 src_mcv
170854 else if (has_avx and src_mcv.isRegister())
170855 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.sse) }
170856 else
170857 try self.copyToRegisterWithInstTracking(inst, src_ty, src_mcv);
170858 const dst_reg = dst_mcv.getReg().?;
170859 const dst_alias = registerAlias(dst_reg, dst_abi_size);
170860
170861 if (has_avx) try self.asmRegisterRegisterRegister(
170862 mir_tag,
170863 dst_alias,
170864 registerAlias(if (src_mcv.isRegister())
170865 src_mcv.getReg().?
170866 else
170867 dst_reg, src_abi_size),
170868 dst_alias,
170869 ) else try self.asmRegisterRegister(
170870 mir_tag,
170871 dst_alias,
170872 dst_alias,
170873 );
170874 break :result dst_mcv;
170875 },
170876 .eq => if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170877 break :result src_mcv
170878 else {
170879 const dst_mcv = try self.allocRegOrMem(inst, true);
170880 try self.genCopy(dst_ty, dst_mcv, src_mcv, .{});
170881 break :result dst_mcv;
170882 },
170883 .gt => if (self.hasFeature(.sse4_1)) {
170884 if (max_abi_size > self.vectorSize(.int)) break :result null;
170885 const mir_tag: Mir.Inst.FixedTag = .{ switch (dst_elem_abi_size) {
170886 else => break :result null,
170887 2 => if (has_avx) .vp_w else .p_w,
170888 4 => if (has_avx) .vp_d else .p_d,
170889 8 => if (has_avx) .vp_q else .p_q,
170890 }, switch (src_elem_abi_size) {
170891 else => break :result null,
170892 1 => switch (extend) {
170893 .signed => .movsxb,
170894 .unsigned => .movzxb,
170895 },
170896 2 => switch (extend) {
170897 .signed => .movsxw,
170898 .unsigned => .movzxw,
170899 },
170900 4 => switch (extend) {
170901 .signed => .movsxd,
170902 .unsigned => .movzxd,
170903 },
170904 } };
170905
170906 const dst_mcv: MCValue = if (src_mcv.isRegister() and
170907 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170908 src_mcv
170909 else
170910 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.sse) };
170911 const dst_reg = dst_mcv.getReg().?;
170912 const dst_alias = registerAlias(dst_reg, dst_abi_size);
170913
170914 if (src_mcv.isBase()) try self.asmRegisterMemory(
170915 mir_tag,
170916 dst_alias,
170917 try src_mcv.mem(self, .{ .size = self.memSize(src_ty) }),
170918 ) else try self.asmRegisterRegister(
170919 mir_tag,
170920 dst_alias,
170921 registerAlias(if (src_mcv.isRegister())
170922 src_mcv.getReg().?
170923 else
170924 try self.copyToTmpRegister(src_ty, src_mcv), src_abi_size),
170925 );
170926 break :result dst_mcv;
170927 } else {
170928 const mir_tag: Mir.Inst.FixedTag = switch (dst_elem_abi_size) {
170929 else => break :result null,
170930 2 => switch (src_elem_abi_size) {
170931 else => break :result null,
170932 1 => .{ .p_, .unpcklbw },
170933 },
170934 4 => switch (src_elem_abi_size) {
170935 else => break :result null,
170936 2 => .{ .p_, .unpcklwd },
170937 },
170938 8 => switch (src_elem_abi_size) {
170939 else => break :result null,
170940 2 => .{ .p_, .unpckldq },
170941 },
170942 };
170943
170944 const dst_mcv: MCValue = if (src_mcv.isRegister() and
170945 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
170946 src_mcv
170947 else
170948 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
170949 const dst_reg = dst_mcv.getReg().?;
170950
170951 const ext_reg = try self.register_manager.allocReg(null, abi.RegisterClass.sse);
170952 const ext_alias = registerAlias(ext_reg, src_abi_size);
170953 const ext_lock = self.register_manager.lockRegAssumeUnused(ext_reg);
170954 defer self.register_manager.unlockReg(ext_lock);
170955
170956 try self.asmRegisterRegister(.{ .p_, .xor }, ext_alias, ext_alias);
170957 switch (extend) {
170958 .signed => try self.asmRegisterRegister(
170959 .{ switch (src_elem_abi_size) {
170960 else => unreachable,
170961 1 => .p_b,
170962 2 => .p_w,
170963 4 => .p_d,
170964 }, .cmpgt },
170965 ext_alias,
170966 registerAlias(dst_reg, src_abi_size),
170967 ),
170968 .unsigned => {},
170969 }
170970 try self.asmRegisterRegister(
170971 mir_tag,
170972 registerAlias(dst_reg, dst_abi_size),
170973 registerAlias(ext_reg, dst_abi_size),
170974 );
170975 break :result dst_mcv;
170976 },
170977 }
170978 @compileError("unreachable");
170979 }
170980
170981 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
170982
170983 const src_storage_bits: u16 = switch (src_mcv) {
170984 .register, .register_offset => 64,
170985 .register_pair => 128,
170986 .load_frame => |frame_addr| @intCast(self.getFrameAddrSize(frame_addr) * 8),
170987 else => src_int_info.bits,
170988 };
170989
170990 const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else src_abi_size > 8) and
170991 dst_int_info.bits <= src_storage_bits and
170992 std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
170993 std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and
170994 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
170995 const dst_mcv = try self.allocRegOrMem(inst, true);
170996 try self.genCopy(min_ty, dst_mcv, src_mcv, .{});
170997 break :dst dst_mcv;
170998 };
170999
171000 if (dst_int_info.bits <= src_int_info.bits) break :result if (dst_mcv.isRegister())
171001 .{ .register = registerAlias(dst_mcv.getReg().?, dst_abi_size) }
171002 else
171003 dst_mcv;
171004
171005 if (dst_mcv.isRegister()) {
171006 try self.truncateRegister(src_ty, dst_mcv.getReg().?);
171007 break :result .{ .register = registerAlias(dst_mcv.getReg().?, dst_abi_size) };
171008 }
171009
171010 const src_limbs_len = std.math.divCeil(u31, src_abi_size, 8) catch unreachable;
171011 const dst_limbs_len = @divExact(dst_abi_size, 8);
171012
171013 const high_mcv: MCValue = if (dst_mcv.isBase())
171014 dst_mcv.address().offset((src_limbs_len - 1) * 8).deref()
171015 else
171016 .{ .register = dst_mcv.register_pair[1] };
171017 const high_reg = if (high_mcv.isRegister())
171018 high_mcv.getReg().?
171019 else
171020 try self.copyToTmpRegister(switch (src_int_info.signedness) {
171021 .signed => .isize,
171022 .unsigned => .usize,
171023 }, high_mcv);
171024 const high_lock = self.register_manager.lockRegAssumeUnused(high_reg);
171025 defer self.register_manager.unlockReg(high_lock);
171026
171027 const high_bits = src_int_info.bits % 64;
171028 if (high_bits > 0) {
171029 try self.truncateRegister(src_ty, high_reg);
171030 const high_ty: Type = if (dst_int_info.bits >= 64) .usize else dst_ty;
171031 try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }, .{});
171032 }
171033
171034 if (dst_limbs_len > src_limbs_len) try self.genInlineMemset(
171035 dst_mcv.address().offset(src_limbs_len * 8),
171036 switch (extend) {
171037 .signed => extend: {
171038 const extend_mcv = MCValue{ .register = high_reg };
171039 try self.genShiftBinOpMir(.{ ._r, .sa }, .isize, extend_mcv, .u8, .{ .immediate = 63 });
171040 break :extend extend_mcv;
171041 },
171042 .unsigned => .{ .immediate = 0 },
171043 },
171044 .{ .immediate = (dst_limbs_len - src_limbs_len) * 8 },
171045 .{},
171046 );
171047
171048 break :result dst_mcv;
171049 }) orelse return self.fail("TODO implement airIntCast from {f} to {f}", .{
171050 src_ty.fmt(pt), dst_ty.fmt(pt),
171051 });
171052 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
171053}
171054
171055fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
171056 const pt = self.pt;
171057 const zcu = pt.zcu;
171058 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
171059
171060 const dst_ty = self.typeOfIndex(inst);
171061 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu));
171062 const src_ty = self.typeOf(ty_op.operand);
171063 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
171064
171065 const result = result: {
171066 const src_mcv = try self.resolveInst(ty_op.operand);
171067 const src_lock =
171068 if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null;
171069 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
171070
171071 const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.isClass(self.regClassForType(dst_ty)) and
171072 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
171073 src_mcv
171074 else if (dst_abi_size <= 8)
171075 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv)
171076 else if (dst_abi_size <= 16 and !dst_ty.isVector(zcu)) dst: {
171077 const dst_regs =
171078 try self.register_manager.allocRegs(2, .{ inst, inst }, abi.RegisterClass.gp);
171079 const dst_mcv: MCValue = .{ .register_pair = dst_regs };
171080 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
171081 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
171082
171083 try self.genCopy(dst_ty, dst_mcv, src_mcv, .{});
171084 break :dst dst_mcv;
171085 } else dst: {
171086 const dst_mcv = try self.allocRegOrMemAdvanced(src_ty, inst, true);
171087 try self.genCopy(src_ty, dst_mcv, src_mcv, .{});
171088 break :dst dst_mcv;
171089 };
171090
171091 if (dst_ty.zigTypeTag(zcu) == .vector) {
171092 assert(src_ty.zigTypeTag(zcu) == .vector and dst_ty.vectorLen(zcu) == src_ty.vectorLen(zcu));
171093 const dst_elem_ty = dst_ty.childType(zcu);
171094 const dst_elem_abi_size: u32 = @intCast(dst_elem_ty.abiSize(zcu));
171095 const src_elem_ty = src_ty.childType(zcu);
171096 const src_elem_abi_size: u32 = @intCast(src_elem_ty.abiSize(zcu));
171097
171098 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_elem_abi_size) {
171099 1 => switch (src_elem_abi_size) {
171100 2 => switch (dst_ty.vectorLen(zcu)) {
171101 1...8 => if (self.hasFeature(.avx)) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw },
171102 9...16 => if (self.hasFeature(.avx2)) .{ .vp_b, .ackusw } else null,
171103 else => null,
171104 },
171105 else => null,
171106 },
171107 2 => switch (src_elem_abi_size) {
171108 4 => switch (dst_ty.vectorLen(zcu)) {
171109 1...4 => if (self.hasFeature(.avx))
171110 .{ .vp_w, .ackusd }
171111 else if (self.hasFeature(.sse4_1))
171112 .{ .p_w, .ackusd }
171113 else
171114 null,
171115 5...8 => if (self.hasFeature(.avx2)) .{ .vp_w, .ackusd } else null,
171116 else => null,
171117 },
171118 else => null,
171119 },
171120 else => null,
171121 }) orelse return self.fail("TODO implement airTrunc for {f}", .{dst_ty.fmt(pt)});
171122
171123 const dst_info = dst_elem_ty.intInfo(zcu);
171124 const src_info = src_elem_ty.intInfo(zcu);
171125
171126 const mask_val = try pt.intValue(src_elem_ty, @as(u64, std.math.maxInt(u64)) >> @intCast(64 - dst_info.bits));
171127
171128 const splat_ty = try pt.vectorType(.{
171129 .len = @intCast(@divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)),
171130 .child = src_elem_ty.ip_index,
171131 });
171132 const splat_abi_size: u32 = @intCast(splat_ty.abiSize(zcu));
171133
171134 const splat_val = try pt.aggregateSplatValue(splat_ty, mask_val);
171135
171136 const splat_mcv = try self.lowerValue(splat_val);
171137 const splat_addr_mcv: MCValue = switch (splat_mcv) {
171138 .memory, .indirect, .load_frame => splat_mcv.address(),
171139 else => .{ .register = try self.copyToTmpRegister(.usize, splat_mcv.address()) },
171140 };
171141
171142 const dst_reg = dst_mcv.getReg().?;
171143 const dst_alias = registerAlias(dst_reg, src_abi_size);
171144 if (self.hasFeature(.avx)) {
171145 try self.asmRegisterRegisterMemory(
171146 .{ .vp_, .@"and" },
171147 dst_alias,
171148 dst_alias,
171149 try splat_addr_mcv.deref().mem(self, .{ .size = .fromSize(splat_abi_size) }),
171150 );
171151 if (src_abi_size > 16) {
171152 const temp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.sse);
171153 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
171154 defer self.register_manager.unlockReg(temp_lock);
171155
171156 try self.asmRegisterRegisterImmediate(
171157 .{ if (self.hasFeature(.avx2)) .v_i128 else .v_f128, .extract },
171158 registerAlias(temp_reg, dst_abi_size),
171159 dst_alias,
171160 .u(1),
171161 );
171162 try self.asmRegisterRegisterRegister(
171163 mir_tag,
171164 registerAlias(dst_reg, dst_abi_size),
171165 registerAlias(dst_reg, dst_abi_size),
171166 registerAlias(temp_reg, dst_abi_size),
171167 );
171168 } else try self.asmRegisterRegisterRegister(mir_tag, dst_alias, dst_alias, dst_alias);
171169 } else {
171170 try self.asmRegisterMemory(
171171 .{ .p_, .@"and" },
171172 dst_alias,
171173 try splat_addr_mcv.deref().mem(self, .{ .size = .fromSize(splat_abi_size) }),
171174 );
171175 try self.asmRegisterRegister(mir_tag, dst_alias, dst_alias);
171176 }
171177 break :result dst_mcv;
171178 }
171179
171180 // when truncating a `u16` to `u5`, for example, those top 3 bits in the result
171181 // have to be removed. this only happens if the dst if not a power-of-two size.
171182 if (dst_abi_size <= 8) {
171183 if (self.regExtraBits(dst_ty) > 0) {
171184 try self.truncateRegister(dst_ty, dst_mcv.register.to64());
171185 }
171186 } else if (dst_abi_size <= 16) {
171187 const dst_info = dst_ty.intInfo(zcu);
171188 const high_ty = try pt.intType(dst_info.signedness, dst_info.bits - 64);
171189 if (self.regExtraBits(high_ty) > 0) {
171190 try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64());
171191 }
171192 }
171193
171194 break :result dst_mcv;
171195 };
171196 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
171197}
171198
171199fn airSlice(self: *CodeGen, inst: Air.Inst.Index) !void {
171200 const zcu = self.pt.zcu;
171201 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
171202 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
171203
171204 const slice_ty = self.typeOfIndex(inst);
171205 const frame_index = try self.allocFrameIndex(.initSpill(slice_ty, zcu));
171206
171207 const ptr_ty = self.typeOf(bin_op.lhs);
171208 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{});
171209
171210 const len_ty = self.typeOf(bin_op.rhs);
171211 try self.genSetMem(
171212 .{ .frame = frame_index },
171213 @intCast(ptr_ty.abiSize(zcu)),
171214 len_ty,
171215 .{ .air_ref = bin_op.rhs },
171216 .{},
171217 );
171218
171219 const result = MCValue{ .load_frame = .{ .index = frame_index } };
171220 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171221}
171222
171223fn airUnOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
171224 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
171225 const dst_mcv = try self.genUnOp(inst, tag, ty_op.operand);
171226 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
171227}
171228
171229fn airBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
171230 const pt = self.pt;
171231 const zcu = pt.zcu;
171232 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
171233 const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);
171234
171235 const dst_ty = self.typeOfIndex(inst);
171236 if (dst_ty.isAbiInt(zcu)) {
171237 const abi_size: u32 = @intCast(dst_ty.abiSize(zcu));
171238 const bit_size: u32 = @intCast(dst_ty.bitSize(zcu));
171239 if (abi_size * 8 > bit_size) {
171240 const dst_lock = switch (dst_mcv) {
171241 .register => |dst_reg| self.register_manager.lockRegAssumeUnused(dst_reg),
171242 else => null,
171243 };
171244 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
171245
171246 if (dst_mcv.isRegister()) {
171247 try self.truncateRegister(dst_ty, dst_mcv.getReg().?);
171248 } else {
171249 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171250 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
171251 defer self.register_manager.unlockReg(tmp_lock);
171252
171253 const hi_ty = try pt.intType(.unsigned, @intCast((dst_ty.bitSize(zcu) - 1) % 64 + 1));
171254 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();
171255 try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{});
171256 try self.truncateRegister(dst_ty, tmp_reg);
171257 try self.genCopy(hi_ty, hi_mcv, .{ .register = tmp_reg }, .{});
171258 }
171259 }
171260 }
171261 return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none });
171262}
171263
171264fn airPtrArithmetic(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
171265 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
171266 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
171267 const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);
171268 return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none });
171269}
171270
171271fn activeIntBits(self: *CodeGen, dst_air: Air.Inst.Ref) u16 {
171272 const pt = self.pt;
171273 const zcu = pt.zcu;
171274 const air_tag = self.air.instructions.items(.tag);
171275 const air_data = self.air.instructions.items(.data);
171276
171277 const dst_ty = self.typeOf(dst_air);
171278 const dst_info = dst_ty.intInfo(zcu);
171279 if (dst_air.toIndex()) |inst| {
171280 switch (air_tag[@intFromEnum(inst)]) {
171281 .intcast => {
171282 const src_ty = self.typeOf(air_data[@intFromEnum(inst)].ty_op.operand);
171283 const src_info = src_ty.intInfo(zcu);
171284 return @min(switch (src_info.signedness) {
171285 .signed => switch (dst_info.signedness) {
171286 .signed => src_info.bits,
171287 .unsigned => src_info.bits - 1,
171288 },
171289 .unsigned => switch (dst_info.signedness) {
171290 .signed => src_info.bits + 1,
171291 .unsigned => src_info.bits,
171292 },
171293 }, dst_info.bits);
171294 },
171295 else => {},
171296 }
171297 } else if (dst_air.toInterned()) |ip_index| {
171298 var space: Value.BigIntSpace = undefined;
171299 const src_int = Value.fromInterned(ip_index).toBigInt(&space, zcu);
171300 return @as(u16, @intCast(src_int.bitCountTwosComp())) +
171301 @intFromBool(src_int.positive and dst_info.signedness == .signed);
171302 }
171303 return dst_info.bits;
171304}
171305
171306fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
171307 const pt = self.pt;
171308 const zcu = pt.zcu;
171309 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
171310 const result = result: {
171311 const dst_ty = self.typeOfIndex(inst);
171312 switch (dst_ty.zigTypeTag(zcu)) {
171313 .float, .vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
171314 else => {},
171315 }
171316 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu));
171317
171318 const dst_info = dst_ty.intInfo(zcu);
171319 const src_ty = try pt.intType(dst_info.signedness, switch (tag) {
171320 else => unreachable,
171321 .mul, .mul_wrap => @max(
171322 self.activeIntBits(bin_op.lhs),
171323 self.activeIntBits(bin_op.rhs),
171324 dst_info.bits / 2,
171325 ),
171326 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,
171327 });
171328 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
171329
171330 if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) {
171331 else => unreachable,
171332 .mul, .mul_wrap => {},
171333 .div_trunc, .div_floor, .div_exact, .rem, .mod => {
171334 const signed = dst_ty.isSignedInt(zcu);
171335 var sym_buf: ["__udiv?i3".len]u8 = undefined;
171336 const signed_div_floor_state: struct {
171337 frame_index: FrameIndex,
171338 state: State,
171339 reloc: Mir.Inst.Index,
171340 } = if (signed and tag == .div_floor) state: {
171341 const frame_index = try self.allocFrameIndex(.initType(.usize, zcu));
171342 try self.asmMemoryImmediate(
171343 .{ ._, .mov },
171344 .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } },
171345 .u(0),
171346 );
171347
171348 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171349 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
171350 defer self.register_manager.unlockReg(tmp_lock);
171351
171352 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171353 const mat_lhs_mcv = switch (lhs_mcv) {
171354 .load_nav, .load_uav, .load_lazy_sym => mat_lhs_mcv: {
171355 // TODO clean this up!
171356 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
171357 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
171358 },
171359 else => lhs_mcv,
171360 };
171361 const mat_lhs_lock = switch (mat_lhs_mcv) {
171362 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
171363 else => null,
171364 };
171365 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
171366 if (mat_lhs_mcv.isBase()) try self.asmRegisterMemory(
171367 .{ ._, .mov },
171368 tmp_reg,
171369 try mat_lhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
171370 ) else try self.asmRegisterRegister(
171371 .{ ._, .mov },
171372 tmp_reg,
171373 mat_lhs_mcv.register_pair[1],
171374 );
171375
171376 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171377 const mat_rhs_mcv = switch (rhs_mcv) {
171378 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
171379 // TODO clean this up!
171380 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
171381 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
171382 },
171383 else => rhs_mcv,
171384 };
171385 const mat_rhs_lock = switch (mat_rhs_mcv) {
171386 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
171387 else => null,
171388 };
171389 defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
171390 if (mat_rhs_mcv.isBase()) try self.asmRegisterMemory(
171391 .{ ._, .xor },
171392 tmp_reg,
171393 try mat_rhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
171394 ) else try self.asmRegisterRegister(
171395 .{ ._, .xor },
171396 tmp_reg,
171397 mat_rhs_mcv.register_pair[1],
171398 );
171399 const state = try self.saveState();
171400 const reloc = try self.asmJccReloc(.ns, undefined);
171401
171402 break :state .{ .frame_index = frame_index, .state = state, .reloc = reloc };
171403 } else undefined;
171404 const call_mcv = try self.genCall(
171405 .{ .extern_func = .{
171406 .return_type = dst_ty.toIntern(),
171407 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },
171408 .sym = std.fmt.bufPrint(&sym_buf, "__{s}{s}{c}i3", .{
171409 if (signed) "" else "u",
171410 switch (tag) {
171411 .div_trunc, .div_exact => "div",
171412 .div_floor => if (signed) "mod" else "div",
171413 .rem, .mod => "mod",
171414 else => unreachable,
171415 },
171416 intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))),
171417 }) catch unreachable,
171418 } },
171419 &.{ src_ty, src_ty },
171420 &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } },
171421 .{},
171422 );
171423 break :result if (signed) switch (tag) {
171424 .div_floor => {
171425 try self.asmRegisterRegister(
171426 .{ ._, .@"or" },
171427 call_mcv.register_pair[0],
171428 call_mcv.register_pair[1],
171429 );
171430 try self.asmSetccMemory(.nz, .{
171431 .base = .{ .frame = signed_div_floor_state.frame_index },
171432 .mod = .{ .rm = .{ .size = .byte } },
171433 });
171434 try self.restoreState(signed_div_floor_state.state, &.{}, .{
171435 .emit_instructions = true,
171436 .update_tracking = true,
171437 .resurrect = true,
171438 .close_scope = true,
171439 });
171440 self.performReloc(signed_div_floor_state.reloc);
171441 const dst_mcv = try self.genCall(
171442 .{ .extern_func = .{
171443 .return_type = dst_ty.toIntern(),
171444 .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() },
171445 .sym = std.fmt.bufPrint(&sym_buf, "__div{c}i3", .{
171446 intCompilerRtAbiName(@intCast(dst_ty.bitSize(zcu))),
171447 }) catch unreachable,
171448 } },
171449 &.{ src_ty, src_ty },
171450 &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } },
171451 .{},
171452 );
171453 try self.asmRegisterMemory(
171454 .{ ._, .sub },
171455 dst_mcv.register_pair[0],
171456 .{
171457 .base = .{ .frame = signed_div_floor_state.frame_index },
171458 .mod = .{ .rm = .{ .size = .qword } },
171459 },
171460 );
171461 try self.asmRegisterImmediate(.{ ._, .sbb }, dst_mcv.register_pair[1], .u(0));
171462 try self.freeValue(
171463 .{ .load_frame = .{ .index = signed_div_floor_state.frame_index } },
171464 );
171465 break :result dst_mcv;
171466 },
171467 .mod => {
171468 const dst_regs = call_mcv.register_pair;
171469 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
171470 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
171471
171472 const tmp_regs =
171473 try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp);
171474 const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs);
171475 defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock);
171476
171477 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171478 const mat_rhs_mcv = switch (rhs_mcv) {
171479 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
171480 // TODO clean this up!
171481 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
171482 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
171483 },
171484 else => rhs_mcv,
171485 };
171486 const mat_rhs_lock = switch (mat_rhs_mcv) {
171487 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
171488 else => null,
171489 };
171490 defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
171491
171492 for (tmp_regs, dst_regs) |tmp_reg, dst_reg|
171493 try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg);
171494 if (mat_rhs_mcv.isBase()) {
171495 try self.asmRegisterMemory(
171496 .{ ._, .add },
171497 tmp_regs[0],
171498 try mat_rhs_mcv.mem(self, .{ .size = .qword }),
171499 );
171500 try self.asmRegisterMemory(
171501 .{ ._, .adc },
171502 tmp_regs[1],
171503 try mat_rhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
171504 );
171505 } else for (
171506 [_]Mir.Inst.Tag{ .add, .adc },
171507 tmp_regs,
171508 mat_rhs_mcv.register_pair,
171509 ) |op, tmp_reg, rhs_reg|
171510 try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg);
171511 try self.asmRegisterRegister(.{ ._, .@"test" }, dst_regs[1], dst_regs[1]);
171512 for (dst_regs, tmp_regs) |dst_reg, tmp_reg|
171513 try self.asmCmovccRegisterRegister(.s, dst_reg, tmp_reg);
171514 break :result call_mcv;
171515 },
171516 else => call_mcv,
171517 } else call_mcv;
171518 },
171519 };
171520
171521 try self.spillEflagsIfOccupied();
171522 try self.spillRegisters(&.{ .rax, .rcx, .rdx });
171523 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx });
171524 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
171525
171526 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171527 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171528 break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs_mcv, rhs_mcv);
171529 };
171530 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171531}
171532
171533fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void {
171534 const pt = self.pt;
171535 const zcu = pt.zcu;
171536 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
171537 const ty = self.typeOf(bin_op.lhs);
171538 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
171539 "TODO implement airAddSat for {f}",
171540 .{ty.fmt(pt)},
171541 );
171542
171543 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171544 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
171545 lhs_mcv
171546 else
171547 try self.copyToRegisterWithInstTracking(inst, ty, lhs_mcv);
171548 const dst_reg = dst_mcv.register;
171549 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
171550 defer self.register_manager.unlockReg(dst_lock);
171551
171552 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171553 const rhs_lock = switch (rhs_mcv) {
171554 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
171555 else => null,
171556 };
171557 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
171558
171559 const limit_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171560 const limit_mcv = MCValue{ .register = limit_reg };
171561 const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg);
171562 defer self.register_manager.unlockReg(limit_lock);
171563
171564 const reg_bits = self.regBitSize(ty);
171565 const reg_extra_bits = self.regExtraBits(ty);
171566 const cc: Condition = if (ty.isSignedInt(zcu)) cc: {
171567 if (reg_extra_bits > 0) {
171568 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits });
171569 }
171570 try self.genSetReg(limit_reg, ty, dst_mcv, .{});
171571 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 });
171572 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
171573 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
171574 });
171575 if (reg_extra_bits > 0) {
171576 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
171577 const shifted_rhs_mcv = MCValue{ .register = shifted_rhs_reg };
171578 const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg);
171579 defer self.register_manager.unlockReg(shifted_rhs_lock);
171580
171581 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, shifted_rhs_mcv, .u8, .{ .immediate = reg_extra_bits });
171582 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv);
171583 } else try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
171584 break :cc .o;
171585 } else cc: {
171586 try self.genSetReg(limit_reg, ty, .{
171587 .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - ty.bitSize(zcu)),
171588 }, .{});
171589
171590 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
171591 if (reg_extra_bits > 0) {
171592 try self.genBinOpMir(.{ ._, .cmp }, ty, dst_mcv, limit_mcv);
171593 break :cc .a;
171594 }
171595 break :cc .c;
171596 };
171597
171598 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2);
171599 try self.asmCmovccRegisterRegister(
171600 cc,
171601 registerAlias(dst_reg, cmov_abi_size),
171602 registerAlias(limit_reg, cmov_abi_size),
171603 );
171604
171605 if (reg_extra_bits > 0 and ty.isSignedInt(zcu))
171606 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits });
171607
171608 return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none });
171609}
171610
171611fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void {
171612 const pt = self.pt;
171613 const zcu = pt.zcu;
171614 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
171615 const ty = self.typeOf(bin_op.lhs);
171616 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
171617 "TODO implement airSubSat for {f}",
171618 .{ty.fmt(pt)},
171619 );
171620
171621 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171622 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
171623 lhs_mcv
171624 else
171625 try self.copyToRegisterWithInstTracking(inst, ty, lhs_mcv);
171626 const dst_reg = dst_mcv.register;
171627 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
171628 defer self.register_manager.unlockReg(dst_lock);
171629
171630 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171631 const rhs_lock = switch (rhs_mcv) {
171632 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
171633 else => null,
171634 };
171635 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
171636
171637 const limit_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171638 const limit_mcv = MCValue{ .register = limit_reg };
171639 const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg);
171640 defer self.register_manager.unlockReg(limit_lock);
171641
171642 const reg_bits = self.regBitSize(ty);
171643 const reg_extra_bits = self.regExtraBits(ty);
171644 const cc: Condition = if (ty.isSignedInt(zcu)) cc: {
171645 if (reg_extra_bits > 0) {
171646 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits });
171647 }
171648 try self.genSetReg(limit_reg, ty, dst_mcv, .{});
171649 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 });
171650 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
171651 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
171652 });
171653 if (reg_extra_bits > 0) {
171654 const shifted_rhs_reg = try self.copyToTmpRegister(ty, rhs_mcv);
171655 const shifted_rhs_mcv = MCValue{ .register = shifted_rhs_reg };
171656 const shifted_rhs_lock = self.register_manager.lockRegAssumeUnused(shifted_rhs_reg);
171657 defer self.register_manager.unlockReg(shifted_rhs_lock);
171658
171659 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, shifted_rhs_mcv, .u8, .{ .immediate = reg_extra_bits });
171660 try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv);
171661 } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv);
171662 break :cc .o;
171663 } else cc: {
171664 try self.genSetReg(limit_reg, ty, .{ .immediate = 0 }, .{});
171665 try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv);
171666 break :cc .c;
171667 };
171668
171669 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2);
171670 try self.asmCmovccRegisterRegister(
171671 cc,
171672 registerAlias(dst_reg, cmov_abi_size),
171673 registerAlias(limit_reg, cmov_abi_size),
171674 );
171675
171676 if (reg_extra_bits > 0 and ty.isSignedInt(zcu))
171677 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .u8, .{ .immediate = reg_extra_bits });
171678
171679 return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none });
171680}
171681
171682fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
171683 const pt = self.pt;
171684 const zcu = pt.zcu;
171685 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
171686 const ty = self.typeOf(bin_op.lhs);
171687
171688 const result = result: {
171689 if (ty.toIntern() == .i128_type) {
171690 const ptr_c_int = try pt.singleMutPtrType(.c_int);
171691 const overflow = try self.allocTempRegOrMem(.c_int, false);
171692
171693 const dst_mcv = try self.genCall(.{ .extern_func = .{
171694 .return_type = .i128_type,
171695 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },
171696 .sym = "__muloti4",
171697 } }, &.{ .i128, .i128, ptr_c_int }, &.{
171698 .{ .air_ref = bin_op.lhs },
171699 .{ .air_ref = bin_op.rhs },
171700 overflow.address(),
171701 }, .{});
171702 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_mcv.register_pair);
171703 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
171704
171705 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171706 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
171707 defer self.register_manager.unlockReg(tmp_lock);
171708
171709 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171710 const mat_lhs_mcv = switch (lhs_mcv) {
171711 .load_nav, .load_uav, .load_lazy_sym => mat_lhs_mcv: {
171712 // TODO clean this up!
171713 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
171714 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
171715 },
171716 else => lhs_mcv,
171717 };
171718 const mat_lhs_lock = switch (mat_lhs_mcv) {
171719 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
171720 else => null,
171721 };
171722 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
171723 if (mat_lhs_mcv.isBase()) try self.asmRegisterMemory(
171724 .{ ._, .mov },
171725 tmp_reg,
171726 try mat_lhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
171727 ) else try self.asmRegisterRegister(
171728 .{ ._, .mov },
171729 tmp_reg,
171730 mat_lhs_mcv.register_pair[1],
171731 );
171732
171733 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171734 const mat_rhs_mcv = switch (rhs_mcv) {
171735 .load_nav, .load_uav, .load_lazy_sym => mat_rhs_mcv: {
171736 // TODO clean this up!
171737 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
171738 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
171739 },
171740 else => rhs_mcv,
171741 };
171742 const mat_rhs_lock = switch (mat_rhs_mcv) {
171743 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
171744 else => null,
171745 };
171746 defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
171747 if (mat_rhs_mcv.isBase()) try self.asmRegisterMemory(
171748 .{ ._, .xor },
171749 tmp_reg,
171750 try mat_rhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
171751 ) else try self.asmRegisterRegister(
171752 .{ ._, .xor },
171753 tmp_reg,
171754 mat_rhs_mcv.register_pair[1],
171755 );
171756
171757 try self.asmRegisterImmediate(.{ ._r, .sa }, tmp_reg, .u(63));
171758 try self.asmRegister(.{ ._, .not }, tmp_reg);
171759 try self.asmMemoryImmediate(.{ ._, .cmp }, try overflow.mem(self, .{ .size = .dword }), .s(0));
171760 try self.freeValue(overflow);
171761 try self.asmCmovccRegisterRegister(.ne, dst_mcv.register_pair[0], tmp_reg);
171762 try self.asmRegisterImmediate(.{ ._c, .bt }, tmp_reg, .u(63));
171763 try self.asmCmovccRegisterRegister(.ne, dst_mcv.register_pair[1], tmp_reg);
171764 break :result dst_mcv;
171765 }
171766
171767 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
171768 "TODO implement airMulSat for {f}",
171769 .{ty.fmt(pt)},
171770 );
171771
171772 try self.spillRegisters(&.{ .rax, .rcx, .rdx });
171773 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx });
171774 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
171775
171776 const lhs_mcv = try self.resolveInst(bin_op.lhs);
171777 const lhs_lock = switch (lhs_mcv) {
171778 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
171779 else => null,
171780 };
171781 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
171782
171783 const rhs_mcv = try self.resolveInst(bin_op.rhs);
171784 const rhs_lock = switch (rhs_mcv) {
171785 .register => |reg| self.register_manager.lockReg(reg),
171786 else => null,
171787 };
171788 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
171789
171790 const limit_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
171791 const limit_mcv = MCValue{ .register = limit_reg };
171792 const limit_lock = self.register_manager.lockRegAssumeUnused(limit_reg);
171793 defer self.register_manager.unlockReg(limit_lock);
171794
171795 const reg_bits = self.regBitSize(ty);
171796 const cc: Condition = if (ty.isSignedInt(zcu)) cc: {
171797 try self.genSetReg(limit_reg, ty, lhs_mcv, .{});
171798 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);
171799 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .u8, .{ .immediate = reg_bits - 1 });
171800 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{
171801 .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1,
171802 });
171803 break :cc .o;
171804 } else cc: {
171805 try self.genSetReg(limit_reg, ty, .{
171806 .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - reg_bits),
171807 }, .{});
171808 break :cc .c;
171809 };
171810
171811 const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv);
171812 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2);
171813 try self.asmCmovccRegisterRegister(
171814 cc,
171815 registerAlias(dst_mcv.register, cmov_abi_size),
171816 registerAlias(limit_reg, cmov_abi_size),
171817 );
171818 break :result dst_mcv;
171819 };
171820 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171821}
171822
171823fn airAddSubWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
171824 const pt = self.pt;
171825 const zcu = pt.zcu;
171826 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
171827 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
171828 const result: MCValue = result: {
171829 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
171830 const ty = self.typeOf(bin_op.lhs);
171831 switch (ty.zigTypeTag(zcu)) {
171832 .vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),
171833 .int => {
171834 try self.spillEflagsIfOccupied();
171835 try self.spillRegisters(&.{ .rcx, .rdi, .rsi });
171836 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rcx, .rdi, .rsi });
171837 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
171838
171839 const partial_mcv = try self.genBinOp(null, switch (tag) {
171840 .add_with_overflow => .add,
171841 .sub_with_overflow => .sub,
171842 else => unreachable,
171843 }, bin_op.lhs, bin_op.rhs);
171844 const int_info = ty.intInfo(zcu);
171845 const cc: Condition = switch (int_info.signedness) {
171846 .unsigned => .c,
171847 .signed => .o,
171848 };
171849
171850 const tuple_ty = self.typeOfIndex(inst);
171851 if (int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits)) {
171852 switch (partial_mcv) {
171853 .register => |reg| {
171854 self.eflags_inst = inst;
171855 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
171856 },
171857 else => {},
171858 }
171859
171860 const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
171861 try self.genSetMem(
171862 .{ .frame = frame_index },
171863 @intCast(tuple_ty.structFieldOffset(1, zcu)),
171864 .u1,
171865 .{ .eflags = cc },
171866 .{},
171867 );
171868 try self.genSetMem(
171869 .{ .frame = frame_index },
171870 @intCast(tuple_ty.structFieldOffset(0, zcu)),
171871 ty,
171872 partial_mcv,
171873 .{},
171874 );
171875 break :result .{ .load_frame = .{ .index = frame_index } };
171876 }
171877
171878 const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
171879 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
171880 break :result .{ .load_frame = .{ .index = frame_index } };
171881 },
171882 else => unreachable,
171883 }
171884 };
171885 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171886}
171887
171888fn airShlWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
171889 const pt = self.pt;
171890 const zcu = pt.zcu;
171891 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
171892 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
171893 const result: MCValue = result: {
171894 const lhs_ty = self.typeOf(bin_op.lhs);
171895 const rhs_ty = self.typeOf(bin_op.rhs);
171896 switch (lhs_ty.zigTypeTag(zcu)) {
171897 .vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),
171898 .int => {
171899 try self.spillEflagsIfOccupied();
171900 try self.spillRegisters(&.{ .rcx, .rdi, .rsi });
171901 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rcx, .rdi, .rsi });
171902 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
171903
171904 const lhs = try self.resolveInst(bin_op.lhs);
171905 const rhs = try self.resolveInst(bin_op.rhs);
171906
171907 const int_info = lhs_ty.intInfo(zcu);
171908
171909 const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty);
171910 const partial_lock = switch (partial_mcv) {
171911 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
171912 else => null,
171913 };
171914 defer if (partial_lock) |lock| self.register_manager.unlockReg(lock);
171915
171916 const tmp_mcv = try self.genShiftBinOp(.shr, null, partial_mcv, rhs, lhs_ty, rhs_ty);
171917 const tmp_lock = switch (tmp_mcv) {
171918 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
171919 else => null,
171920 };
171921 defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock);
171922
171923 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, tmp_mcv, lhs);
171924 const cc = Condition.ne;
171925
171926 const tuple_ty = self.typeOfIndex(inst);
171927 if (int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits)) {
171928 switch (partial_mcv) {
171929 .register => |reg| {
171930 self.eflags_inst = inst;
171931 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
171932 },
171933 else => {},
171934 }
171935
171936 const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
171937 try self.genSetMem(
171938 .{ .frame = frame_index },
171939 @intCast(tuple_ty.structFieldOffset(1, zcu)),
171940 tuple_ty.fieldType(1, zcu),
171941 .{ .eflags = cc },
171942 .{},
171943 );
171944 try self.genSetMem(
171945 .{ .frame = frame_index },
171946 @intCast(tuple_ty.structFieldOffset(0, zcu)),
171947 tuple_ty.fieldType(0, zcu),
171948 partial_mcv,
171949 .{},
171950 );
171951 break :result .{ .load_frame = .{ .index = frame_index } };
171952 }
171953
171954 const frame_index =
171955 try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
171956 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
171957 break :result .{ .load_frame = .{ .index = frame_index } };
171958 },
171959 else => unreachable,
171960 }
171961 };
171962 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171963}
171964
171965fn genSetFrameTruncatedOverflowCompare(
171966 self: *CodeGen,
171967 tuple_ty: Type,
171968 frame_index: FrameIndex,
171969 src_mcv: MCValue,
171970 overflow_cc: ?Condition,
171971) !void {
171972 const pt = self.pt;
171973 const zcu = pt.zcu;
171974 const src_lock = switch (src_mcv) {
171975 .register => |reg| self.register_manager.lockReg(reg),
171976 else => null,
171977 };
171978 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
171979
171980 const ty = tuple_ty.fieldType(0, zcu);
171981 const ty_size = ty.abiSize(zcu);
171982 const int_info = ty.intInfo(zcu);
171983
171984 const hi_bits = (int_info.bits - 1) % 64 + 1;
171985 const hi_ty = try pt.intType(int_info.signedness, hi_bits);
171986
171987 const limb_bits: u16 = @intCast(if (int_info.bits <= 64) self.regBitSize(ty) else 64);
171988 const limb_ty = try pt.intType(int_info.signedness, limb_bits);
171989
171990 const rest_ty = try pt.intType(.unsigned, int_info.bits - hi_bits);
171991
171992 const temp_regs =
171993 try self.register_manager.allocRegs(3, @splat(null), abi.RegisterClass.gp);
171994 const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);
171995 defer for (temp_locks) |lock| self.register_manager.unlockReg(lock);
171996
171997 const overflow_reg = temp_regs[0];
171998 if (overflow_cc) |cc| try self.asmSetccRegister(cc, overflow_reg.to8());
171999
172000 const scratch_reg = temp_regs[1];
172001 const hi_limb_off = if (int_info.bits <= 64) 0 else (int_info.bits - 1) / 64 * 8;
172002 const hi_limb_mcv = if (hi_limb_off > 0)
172003 src_mcv.address().offset(int_info.bits / 64 * 8).deref()
172004 else
172005 src_mcv;
172006 try self.genSetReg(scratch_reg, limb_ty, hi_limb_mcv, .{});
172007 try self.truncateRegister(hi_ty, scratch_reg);
172008 try self.genBinOpMir(.{ ._, .cmp }, limb_ty, .{ .register = scratch_reg }, hi_limb_mcv);
172009
172010 const eq_reg = temp_regs[2];
172011 if (overflow_cc) |_| {
172012 try self.asmSetccRegister(.ne, eq_reg.to8());
172013 try self.genBinOpMir(.{ ._, .@"or" }, .u8, .{ .register = overflow_reg }, .{ .register = eq_reg });
172014 }
172015 try self.genSetMem(
172016 .{ .frame = frame_index },
172017 @intCast(tuple_ty.structFieldOffset(1, zcu)),
172018 tuple_ty.fieldType(1, zcu),
172019 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
172020 .{},
172021 );
172022
172023 const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu));
172024 if (hi_limb_off > 0) try self.genSetMem(
172025 .{ .frame = frame_index },
172026 payload_off,
172027 rest_ty,
172028 src_mcv,
172029 .{},
172030 );
172031 try self.genSetMem(
172032 .{ .frame = frame_index },
172033 payload_off + hi_limb_off,
172034 limb_ty,
172035 .{ .register = scratch_reg },
172036 .{},
172037 );
172038 var ext_off: i32 = hi_limb_off + 8;
172039 if (ext_off < ty_size) {
172040 switch (int_info.signedness) {
172041 .signed => try self.asmRegisterImmediate(.{ ._r, .sa }, scratch_reg.to64(), .s(63)),
172042 .unsigned => try self.asmRegisterRegister(.{ ._, .xor }, scratch_reg.to32(), scratch_reg.to32()),
172043 }
172044 while (ext_off < ty_size) : (ext_off += 8) try self.genSetMem(
172045 .{ .frame = frame_index },
172046 payload_off + ext_off,
172047 limb_ty,
172048 .{ .register = scratch_reg },
172049 .{},
172050 );
172051 }
172052}
172053
172054fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
172055 const pt = self.pt;
172056 const zcu = pt.zcu;
172057 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
172058 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
172059 const tuple_ty = self.typeOfIndex(inst);
172060 const dst_ty = self.typeOf(bin_op.lhs);
172061 const result: MCValue = switch (dst_ty.zigTypeTag(zcu)) {
172062 .vector => return self.fail("TODO implement airMulWithOverflow for {f}", .{dst_ty.fmt(pt)}),
172063 .int => result: {
172064 const dst_info = dst_ty.intInfo(zcu);
172065 if (dst_info.bits > 128 and dst_info.signedness == .unsigned) {
172066 const slow_inc = self.hasFeature(.slow_incdec);
172067 const abi_size: u32 = @intCast(dst_ty.abiSize(zcu));
172068 const limb_len = std.math.divCeil(u32, abi_size, 8) catch unreachable;
172069
172070 try self.spillRegisters(&.{ .rax, .rcx, .rdx });
172071 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx });
172072 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
172073
172074 const dst_mcv = try self.allocRegOrMem(inst, false);
172075 try self.genInlineMemset(
172076 dst_mcv.address(),
172077 .{ .immediate = 0 },
172078 .{ .immediate = tuple_ty.abiSize(zcu) },
172079 .{},
172080 );
172081 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172082 const rhs_mcv = try self.resolveInst(bin_op.rhs);
172083
172084 const temp_regs =
172085 try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp);
172086 const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs);
172087 defer for (temp_locks) |lock| self.register_manager.unlockReg(lock);
172088
172089 try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[0].to32(), temp_regs[0].to32());
172090
172091 const outer_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
172092 try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[1].to64(), .{
172093 .base = .{ .frame = rhs_mcv.load_frame.index },
172094 .mod = .{ .rm = .{
172095 .size = .qword,
172096 .index = temp_regs[0].to64(),
172097 .scale = .@"8",
172098 .disp = rhs_mcv.load_frame.off,
172099 } },
172100 });
172101 try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64());
172102 const skip_inner = try self.asmJccReloc(.z, undefined);
172103
172104 try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[2].to32(), temp_regs[2].to32());
172105 try self.asmRegisterRegister(.{ ._, .mov }, temp_regs[3].to32(), temp_regs[0].to32());
172106 try self.asmRegisterRegister(.{ ._, .xor }, .ecx, .ecx);
172107 try self.asmRegisterRegister(.{ ._, .xor }, .edx, .edx);
172108
172109 const inner_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
172110 try self.asmRegisterImmediate(.{ ._r, .sh }, .cl, .u(1));
172111 try self.asmMemoryRegister(.{ ._, .adc }, .{
172112 .base = .{ .frame = dst_mcv.load_frame.index },
172113 .mod = .{ .rm = .{
172114 .size = .qword,
172115 .index = temp_regs[3].to64(),
172116 .scale = .@"8",
172117 .disp = dst_mcv.load_frame.off +
172118 @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))),
172119 } },
172120 }, .rdx);
172121 try self.asmSetccRegister(.c, .cl);
172122
172123 try self.asmRegisterMemory(.{ ._, .mov }, .rax, .{
172124 .base = .{ .frame = lhs_mcv.load_frame.index },
172125 .mod = .{ .rm = .{
172126 .size = .qword,
172127 .index = temp_regs[2].to64(),
172128 .scale = .@"8",
172129 .disp = lhs_mcv.load_frame.off,
172130 } },
172131 });
172132 try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64());
172133
172134 try self.asmRegisterImmediate(.{ ._r, .sh }, .ch, .u(1));
172135 try self.asmMemoryRegister(.{ ._, .adc }, .{
172136 .base = .{ .frame = dst_mcv.load_frame.index },
172137 .mod = .{ .rm = .{
172138 .size = .qword,
172139 .index = temp_regs[3].to64(),
172140 .scale = .@"8",
172141 .disp = dst_mcv.load_frame.off +
172142 @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))),
172143 } },
172144 }, .rax);
172145 try self.asmSetccRegister(.c, .ch);
172146
172147 if (slow_inc) {
172148 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1));
172149 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), .u(1));
172150 } else {
172151 try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32());
172152 try self.asmRegister(.{ ._c, .in }, temp_regs[3].to32());
172153 }
172154 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[3].to32(), .u(limb_len));
172155 _ = try self.asmJccReloc(.b, inner_loop);
172156
172157 try self.asmRegisterRegister(.{ ._, .@"or" }, .rdx, .rcx);
172158 const overflow = try self.asmJccReloc(.nz, undefined);
172159 const overflow_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
172160 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[2].to32(), .u(limb_len));
172161 const no_overflow = try self.asmJccReloc(.nb, undefined);
172162 if (slow_inc) {
172163 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1));
172164 } else {
172165 try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32());
172166 }
172167 try self.asmMemoryImmediate(.{ ._, .cmp }, .{
172168 .base = .{ .frame = lhs_mcv.load_frame.index },
172169 .mod = .{ .rm = .{
172170 .size = .qword,
172171 .index = temp_regs[2].to64(),
172172 .scale = .@"8",
172173 .disp = lhs_mcv.load_frame.off - 8,
172174 } },
172175 }, .u(0));
172176 _ = try self.asmJccReloc(.z, overflow_loop);
172177 self.performReloc(overflow);
172178 try self.asmMemoryImmediate(.{ ._, .mov }, .{
172179 .base = .{ .frame = dst_mcv.load_frame.index },
172180 .mod = .{ .rm = .{
172181 .size = .byte,
172182 .disp = dst_mcv.load_frame.off +
172183 @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))),
172184 } },
172185 }, .u(1));
172186 self.performReloc(no_overflow);
172187
172188 self.performReloc(skip_inner);
172189 if (slow_inc) {
172190 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
172191 } else {
172192 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
172193 }
172194 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[0].to32(), .u(limb_len));
172195 _ = try self.asmJccReloc(.b, outer_loop);
172196
172197 break :result dst_mcv;
172198 }
172199
172200 const lhs_active_bits = self.activeIntBits(bin_op.lhs);
172201 const rhs_active_bits = self.activeIntBits(bin_op.rhs);
172202 const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2);
172203 const src_ty = try pt.intType(dst_info.signedness, src_bits);
172204 if (src_bits > 64 and src_bits <= 128 and
172205 dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) {
172206 .signed => {
172207 const ptr_c_int = try pt.singleMutPtrType(.c_int);
172208 const overflow = try self.allocTempRegOrMem(.c_int, false);
172209 const result = try self.genCall(.{ .extern_func = .{
172210 .return_type = .i128_type,
172211 .param_types = &.{ .i128_type, .i128_type, ptr_c_int.toIntern() },
172212 .sym = "__muloti4",
172213 } }, &.{ .i128, .i128, ptr_c_int }, &.{
172214 .{ .air_ref = bin_op.lhs },
172215 .{ .air_ref = bin_op.rhs },
172216 overflow.address(),
172217 }, .{});
172218
172219 const dst_mcv = try self.allocRegOrMem(inst, false);
172220 try self.genSetMem(
172221 .{ .frame = dst_mcv.load_frame.index },
172222 @intCast(tuple_ty.structFieldOffset(0, zcu)),
172223 tuple_ty.fieldType(0, zcu),
172224 result,
172225 .{},
172226 );
172227 try self.asmMemoryImmediate(
172228 .{ ._, .cmp },
172229 try overflow.mem(self, .{ .size = self.memSize(.c_int) }),
172230 .s(0),
172231 );
172232 try self.genSetMem(
172233 .{ .frame = dst_mcv.load_frame.index },
172234 @intCast(tuple_ty.structFieldOffset(1, zcu)),
172235 tuple_ty.fieldType(1, zcu),
172236 .{ .eflags = .ne },
172237 .{},
172238 );
172239 try self.freeValue(overflow);
172240 break :result dst_mcv;
172241 },
172242 .unsigned => {
172243 try self.spillEflagsIfOccupied();
172244 try self.spillRegisters(&.{ .rax, .rdx });
172245 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
172246 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
172247
172248 const tmp_regs =
172249 try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp);
172250 const tmp_locks = self.register_manager.lockRegsAssumeUnused(4, tmp_regs);
172251 defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock);
172252
172253 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172254 const rhs_mcv = try self.resolveInst(bin_op.rhs);
172255 const mat_lhs_mcv = mat_lhs_mcv: switch (lhs_mcv) {
172256 .register => |lhs_reg| switch (lhs_reg.class()) {
172257 else => lhs_mcv,
172258 .sse => {
172259 const mat_lhs_mcv: MCValue = .{
172260 .register_pair = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp),
172261 };
172262 try self.genCopy(dst_ty, mat_lhs_mcv, lhs_mcv, .{});
172263 break :mat_lhs_mcv mat_lhs_mcv;
172264 },
172265 },
172266 .load_nav, .load_uav, .load_lazy_sym => {
172267 // TODO clean this up!
172268 const addr_reg = try self.copyToTmpRegister(.usize, lhs_mcv.address());
172269 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
172270 },
172271 else => lhs_mcv,
172272 };
172273 const mat_lhs_locks: [2]?RegisterLock = switch (mat_lhs_mcv) {
172274 .register_pair => |mat_lhs_regs| self.register_manager.lockRegs(2, mat_lhs_regs),
172275 .indirect => |reg_off| .{ self.register_manager.lockReg(reg_off.reg), null },
172276 else => @splat(null),
172277 };
172278 defer for (mat_lhs_locks) |mat_lhs_lock| if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
172279 const mat_rhs_mcv = mat_rhs_mcv: switch (rhs_mcv) {
172280 .register => |rhs_reg| switch (rhs_reg.class()) {
172281 else => rhs_mcv,
172282 .sse => {
172283 const mat_rhs_mcv: MCValue = .{
172284 .register_pair = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp),
172285 };
172286 try self.genCopy(dst_ty, mat_rhs_mcv, rhs_mcv, .{});
172287 break :mat_rhs_mcv mat_rhs_mcv;
172288 },
172289 },
172290 .load_nav, .load_uav, .load_lazy_sym => {
172291 // TODO clean this up!
172292 const addr_reg = try self.copyToTmpRegister(.usize, rhs_mcv.address());
172293 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
172294 },
172295 else => rhs_mcv,
172296 };
172297 const mat_rhs_locks: [2]?RegisterLock = switch (mat_rhs_mcv) {
172298 .register_pair => |mat_rhs_regs| self.register_manager.lockRegs(2, mat_rhs_regs),
172299 .indirect => |reg_off| .{ self.register_manager.lockReg(reg_off.reg), null },
172300 else => @splat(null),
172301 };
172302 defer for (mat_rhs_locks) |mat_rhs_lock| if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
172303
172304 if (mat_lhs_mcv.isBase()) try self.asmRegisterMemory(
172305 .{ ._, .mov },
172306 .rax,
172307 try mat_lhs_mcv.mem(self, .{ .size = .qword }),
172308 ) else try self.asmRegisterRegister(
172309 .{ ._, .mov },
172310 .rax,
172311 mat_lhs_mcv.register_pair[0],
172312 );
172313 if (mat_rhs_mcv.isBase()) try self.asmRegisterMemory(
172314 .{ ._, .mov },
172315 tmp_regs[0],
172316 try mat_rhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
172317 ) else try self.asmRegisterRegister(
172318 .{ ._, .mov },
172319 tmp_regs[0],
172320 mat_rhs_mcv.register_pair[1],
172321 );
172322 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
172323 try self.asmSetccRegister(.nz, tmp_regs[1].to8());
172324 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax);
172325 try self.asmSetccRegister(.o, tmp_regs[2].to8());
172326 if (mat_rhs_mcv.isBase())
172327 try self.asmMemory(.{ ._, .mul }, try mat_rhs_mcv.mem(self, .{ .size = .qword }))
172328 else
172329 try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]);
172330 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]);
172331 try self.asmSetccRegister(.c, tmp_regs[3].to8());
172332 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[2].to8(), tmp_regs[3].to8());
172333 if (mat_lhs_mcv.isBase()) try self.asmRegisterMemory(
172334 .{ ._, .mov },
172335 tmp_regs[0],
172336 try mat_lhs_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
172337 ) else try self.asmRegisterRegister(
172338 .{ ._, .mov },
172339 tmp_regs[0],
172340 mat_lhs_mcv.register_pair[1],
172341 );
172342 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
172343 try self.asmSetccRegister(.nz, tmp_regs[3].to8());
172344 try self.asmRegisterRegister(
172345 .{ ._, .@"and" },
172346 tmp_regs[1].to8(),
172347 tmp_regs[3].to8(),
172348 );
172349 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
172350 if (mat_rhs_mcv.isBase()) try self.asmRegisterMemory(
172351 .{ .i_, .mul },
172352 tmp_regs[0],
172353 try mat_rhs_mcv.mem(self, .{ .size = .qword }),
172354 ) else try self.asmRegisterRegister(
172355 .{ .i_, .mul },
172356 tmp_regs[0],
172357 mat_rhs_mcv.register_pair[0],
172358 );
172359 try self.asmSetccRegister(.o, tmp_regs[2].to8());
172360 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
172361 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]);
172362 try self.asmSetccRegister(.c, tmp_regs[2].to8());
172363 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
172364
172365 const dst_mcv = try self.allocRegOrMem(inst, false);
172366 try self.genSetMem(
172367 .{ .frame = dst_mcv.load_frame.index },
172368 @intCast(tuple_ty.structFieldOffset(0, zcu)),
172369 tuple_ty.fieldType(0, zcu),
172370 .{ .register_pair = .{ .rax, .rdx } },
172371 .{},
172372 );
172373 try self.genSetMem(
172374 .{ .frame = dst_mcv.load_frame.index },
172375 @intCast(tuple_ty.structFieldOffset(1, zcu)),
172376 tuple_ty.fieldType(1, zcu),
172377 .{ .register = tmp_regs[1] },
172378 .{},
172379 );
172380 break :result dst_mcv;
172381 },
172382 };
172383
172384 try self.spillEflagsIfOccupied();
172385 try self.spillRegisters(&.{ .rax, .rcx, .rdx, .rdi, .rsi });
172386 const reg_locks = self.register_manager.lockRegsAssumeUnused(5, .{ .rax, .rcx, .rdx, .rdi, .rsi });
172387 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
172388
172389 const cc: Condition = switch (dst_info.signedness) {
172390 .unsigned => .c,
172391 .signed => .o,
172392 };
172393
172394 const lhs = try self.resolveInst(bin_op.lhs);
172395 const rhs = try self.resolveInst(bin_op.rhs);
172396
172397 const extra_bits = if (dst_info.bits <= 64)
172398 self.regExtraBits(dst_ty)
172399 else
172400 dst_info.bits % 64;
172401 const partial_mcv = try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs);
172402
172403 switch (partial_mcv) {
172404 .register => |reg| if (extra_bits == 0) {
172405 self.eflags_inst = inst;
172406 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
172407 } else {
172408 const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
172409 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
172410 break :result .{ .load_frame = .{ .index = frame_index } };
172411 },
172412 else => {
172413 // For now, this is the only supported multiply that doesn't fit in a register.
172414 if (dst_info.bits > 128 or src_bits != 64)
172415 return self.fail("TODO implement airWithOverflow from {f} to {f}", .{
172416 src_ty.fmt(pt), dst_ty.fmt(pt),
172417 });
172418
172419 const frame_index = try self.allocFrameIndex(.initSpill(tuple_ty, zcu));
172420 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
172421 try self.genSetMem(
172422 .{ .frame = frame_index },
172423 @intCast(tuple_ty.structFieldOffset(0, zcu)),
172424 tuple_ty.fieldType(0, zcu),
172425 partial_mcv,
172426 .{},
172427 );
172428 try self.genSetMem(
172429 .{ .frame = frame_index },
172430 @intCast(tuple_ty.structFieldOffset(1, zcu)),
172431 tuple_ty.fieldType(1, zcu),
172432 .{ .immediate = 0 }, // cc being set is impossible
172433 .{},
172434 );
172435 } else try self.genSetFrameTruncatedOverflowCompare(
172436 tuple_ty,
172437 frame_index,
172438 partial_mcv,
172439 null,
172440 );
172441 break :result .{ .load_frame = .{ .index = frame_index } };
172442 },
172443 }
172444 },
172445 else => unreachable,
172446 };
172447 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
172448}
172449
172450/// Generates signed or unsigned integer multiplication/division.
172451/// Clobbers .rax and .rdx registers.
172452/// Quotient is saved in .rax and remainder in .rdx.
172453fn genIntMulDivOpMir(self: *CodeGen, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
172454 const pt = self.pt;
172455 const abi_size: u32 = @intCast(ty.abiSize(pt.zcu));
172456 const bit_size: u32 = @intCast(self.regBitSize(ty));
172457 if (abi_size > 8) {
172458 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
172459 }
172460
172461 try self.genSetReg(.rax, ty, lhs, .{});
172462 switch (tag[1]) {
172463 else => unreachable,
172464 .mul => {},
172465 .div => switch (tag[0]) {
172466 ._ => {
172467 const hi_reg: Register =
172468 switch (bit_size) {
172469 8 => .ah,
172470 16, 32, 64 => .edx,
172471 else => unreachable,
172472 };
172473 try self.asmRegisterRegister(.{ ._, .xor }, hi_reg, hi_reg);
172474 },
172475 .i_ => try self.asmOpOnly(.{ ._, switch (bit_size) {
172476 8 => .cbw,
172477 16 => .cwd,
172478 32 => .cdq,
172479 64 => .cqo,
172480 else => unreachable,
172481 } }),
172482 else => unreachable,
172483 },
172484 }
172485
172486 const mat_rhs: MCValue = switch (rhs) {
172487 .register, .indirect, .load_frame => rhs,
172488 else => .{ .register = try self.copyToTmpRegister(ty, rhs) },
172489 };
172490 switch (mat_rhs) {
172491 .register => |reg| try self.asmRegister(tag, registerAlias(reg, abi_size)),
172492 .memory, .indirect, .load_frame => try self.asmMemory(
172493 tag,
172494 try mat_rhs.mem(self, .{ .size = .fromSize(abi_size) }),
172495 ),
172496 else => unreachable,
172497 }
172498 if (tag[1] == .div and bit_size == 8) try self.asmRegisterRegister(.{ ._, .mov }, .dl, .ah);
172499}
172500
172501/// Always returns a register.
172502/// Clobbers .rax and .rdx registers.
172503fn genInlineIntDivFloor(self: *CodeGen, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
172504 const pt = self.pt;
172505 const zcu = pt.zcu;
172506 const abi_size: u32 = @intCast(ty.abiSize(zcu));
172507 const int_info = ty.intInfo(zcu);
172508 const dividend = switch (lhs) {
172509 .register => |reg| reg,
172510 else => try self.copyToTmpRegister(ty, lhs),
172511 };
172512 const dividend_lock = self.register_manager.lockReg(dividend);
172513 defer if (dividend_lock) |lock| self.register_manager.unlockReg(lock);
172514
172515 const divisor = switch (rhs) {
172516 .register => |reg| reg,
172517 else => try self.copyToTmpRegister(ty, rhs),
172518 };
172519 const divisor_lock = self.register_manager.lockReg(divisor);
172520 defer if (divisor_lock) |lock| self.register_manager.unlockReg(lock);
172521
172522 try self.genIntMulDivOpMir(
172523 switch (int_info.signedness) {
172524 .signed => .{ .i_, .div },
172525 .unsigned => .{ ._, .div },
172526 },
172527 ty,
172528 .{ .register = dividend },
172529 .{ .register = divisor },
172530 );
172531
172532 try self.asmRegisterRegister(
172533 .{ ._, .xor },
172534 registerAlias(divisor, abi_size),
172535 registerAlias(dividend, abi_size),
172536 );
172537 try self.asmRegisterImmediate(
172538 .{ ._r, .sa },
172539 registerAlias(divisor, abi_size),
172540 .u(int_info.bits - 1),
172541 );
172542 try self.asmRegisterRegister(
172543 .{ ._, .@"test" },
172544 registerAlias(.rdx, abi_size),
172545 registerAlias(.rdx, abi_size),
172546 );
172547 try self.asmCmovccRegisterRegister(
172548 .z,
172549 registerAlias(divisor, @max(abi_size, 2)),
172550 registerAlias(.rdx, @max(abi_size, 2)),
172551 );
172552 try self.genBinOpMir(.{ ._, .add }, ty, .{ .register = divisor }, .{ .register = .rax });
172553 return MCValue{ .register = divisor };
172554}
172555
172556fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
172557 const pt = self.pt;
172558 const zcu = pt.zcu;
172559 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
172560
172561 const air_tags = self.air.instructions.items(.tag);
172562 const tag = air_tags[@intFromEnum(inst)];
172563 const lhs_ty = self.typeOf(bin_op.lhs);
172564 const rhs_ty = self.typeOf(bin_op.rhs);
172565 const result: MCValue = result: {
172566 switch (lhs_ty.zigTypeTag(zcu)) {
172567 .int => {
172568 try self.spillRegisters(&.{.rcx});
172569 try self.register_manager.getKnownReg(.rcx, null);
172570 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172571 const rhs_mcv = try self.resolveInst(bin_op.rhs);
172572
172573 const dst_mcv = try self.genShiftBinOp(tag, inst, lhs_mcv, rhs_mcv, lhs_ty, rhs_ty);
172574 switch (tag) {
172575 .shr, .shr_exact, .shl_exact => {},
172576 .shl => switch (dst_mcv) {
172577 .register => |dst_reg| try self.truncateRegister(lhs_ty, dst_reg),
172578 .register_pair => |dst_regs| try self.truncateRegister(lhs_ty, dst_regs[1]),
172579 .load_frame => |frame_addr| {
172580 const tmp_reg =
172581 try self.register_manager.allocReg(null, abi.RegisterClass.gp);
172582 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
172583 defer self.register_manager.unlockReg(tmp_lock);
172584
172585 const lhs_bits: u31 = @intCast(lhs_ty.bitSize(zcu));
172586 const tmp_ty: Type = if (lhs_bits > 64) .usize else lhs_ty;
172587 const off = frame_addr.off + (lhs_bits - 1) / 64 * 8;
172588 try self.genSetReg(
172589 tmp_reg,
172590 tmp_ty,
172591 .{ .load_frame = .{ .index = frame_addr.index, .off = off } },
172592 .{},
172593 );
172594 try self.truncateRegister(lhs_ty, tmp_reg);
172595 try self.genSetMem(
172596 .{ .frame = frame_addr.index },
172597 off,
172598 tmp_ty,
172599 .{ .register = tmp_reg },
172600 .{},
172601 );
172602 },
172603 else => {},
172604 },
172605 else => unreachable,
172606 }
172607 break :result dst_mcv;
172608 },
172609 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
172610 .int => if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.childType(zcu).intInfo(zcu).bits) {
172611 else => null,
172612 16 => switch (lhs_ty.vectorLen(zcu)) {
172613 else => null,
172614 1...8 => switch (tag) {
172615 else => unreachable,
172616 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172617 .signed => if (self.hasFeature(.avx))
172618 .{ .vp_w, .sra }
172619 else
172620 .{ .p_w, .sra },
172621 .unsigned => if (self.hasFeature(.avx))
172622 .{ .vp_w, .srl }
172623 else
172624 .{ .p_w, .srl },
172625 },
172626 .shl, .shl_exact => if (self.hasFeature(.avx))
172627 .{ .vp_w, .sll }
172628 else
172629 .{ .p_w, .sll },
172630 },
172631 9...16 => switch (tag) {
172632 else => unreachable,
172633 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172634 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .sra } else null,
172635 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .srl } else null,
172636 },
172637 .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_w, .sll } else null,
172638 },
172639 },
172640 32 => switch (lhs_ty.vectorLen(zcu)) {
172641 else => null,
172642 1...4 => switch (tag) {
172643 else => unreachable,
172644 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172645 .signed => if (self.hasFeature(.avx))
172646 .{ .vp_d, .sra }
172647 else
172648 .{ .p_d, .sra },
172649 .unsigned => if (self.hasFeature(.avx))
172650 .{ .vp_d, .srl }
172651 else
172652 .{ .p_d, .srl },
172653 },
172654 .shl, .shl_exact => if (self.hasFeature(.avx))
172655 .{ .vp_d, .sll }
172656 else
172657 .{ .p_d, .sll },
172658 },
172659 5...8 => switch (tag) {
172660 else => unreachable,
172661 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172662 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .sra } else null,
172663 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .srl } else null,
172664 },
172665 .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_d, .sll } else null,
172666 },
172667 },
172668 64 => switch (lhs_ty.vectorLen(zcu)) {
172669 else => null,
172670 1...2 => switch (tag) {
172671 else => unreachable,
172672 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172673 .signed => if (self.hasFeature(.avx))
172674 .{ .vp_q, .sra }
172675 else
172676 .{ .p_q, .sra },
172677 .unsigned => if (self.hasFeature(.avx))
172678 .{ .vp_q, .srl }
172679 else
172680 .{ .p_q, .srl },
172681 },
172682 .shl, .shl_exact => if (self.hasFeature(.avx))
172683 .{ .vp_q, .sll }
172684 else
172685 .{ .p_q, .sll },
172686 },
172687 3...4 => switch (tag) {
172688 else => unreachable,
172689 .shr, .shr_exact => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
172690 .signed => if (self.hasFeature(.avx2)) .{ .vp_q, .sra } else null,
172691 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_q, .srl } else null,
172692 },
172693 .shl, .shl_exact => if (self.hasFeature(.avx2)) .{ .vp_q, .sll } else null,
172694 },
172695 },
172696 })) |mir_tag| if (try self.air.value(bin_op.rhs, pt)) |rhs_val| {
172697 switch (zcu.intern_pool.indexToKey(rhs_val.toIntern())) {
172698 .aggregate => |rhs_aggregate| switch (rhs_aggregate.storage) {
172699 .repeated_elem => |rhs_elem| {
172700 const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu));
172701
172702 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172703 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and
172704 self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
172705 .{lhs_mcv.getReg().?} ** 2
172706 else if (lhs_mcv.isRegister() and self.hasFeature(.avx)) .{
172707 try self.register_manager.allocReg(inst, abi.RegisterClass.sse),
172708 lhs_mcv.getReg().?,
172709 } else .{(try self.copyToRegisterWithInstTracking(
172710 inst,
172711 lhs_ty,
172712 lhs_mcv,
172713 )).register} ** 2;
172714 const reg_locks =
172715 self.register_manager.lockRegs(2, .{ dst_reg, lhs_reg });
172716 defer for (reg_locks) |reg_lock| if (reg_lock) |lock|
172717 self.register_manager.unlockReg(lock);
172718
172719 const shift_imm: Immediate =
172720 .u(@intCast(Value.fromInterned(rhs_elem).toUnsignedInt(zcu)));
172721 if (self.hasFeature(.avx)) try self.asmRegisterRegisterImmediate(
172722 mir_tag,
172723 registerAlias(dst_reg, abi_size),
172724 registerAlias(lhs_reg, abi_size),
172725 shift_imm,
172726 ) else {
172727 assert(dst_reg.id() == lhs_reg.id());
172728 try self.asmRegisterImmediate(
172729 mir_tag,
172730 registerAlias(dst_reg, abi_size),
172731 shift_imm,
172732 );
172733 }
172734 break :result .{ .register = dst_reg };
172735 },
172736 else => {},
172737 },
172738 else => {},
172739 }
172740 } else if (bin_op.rhs.toIndex()) |rhs_inst| switch (air_tags[@intFromEnum(rhs_inst)]) {
172741 .splat => {
172742 const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu));
172743
172744 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172745 const dst_reg, const lhs_reg = if (lhs_mcv.isRegister() and
172746 self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
172747 .{lhs_mcv.getReg().?} ** 2
172748 else if (lhs_mcv.isRegister() and self.hasFeature(.avx)) .{
172749 try self.register_manager.allocReg(inst, abi.RegisterClass.sse),
172750 lhs_mcv.getReg().?,
172751 } else .{(try self.copyToRegisterWithInstTracking(
172752 inst,
172753 lhs_ty,
172754 lhs_mcv,
172755 )).register} ** 2;
172756 const reg_locks = self.register_manager.lockRegs(2, .{ dst_reg, lhs_reg });
172757 defer for (reg_locks) |reg_lock| if (reg_lock) |lock|
172758 self.register_manager.unlockReg(lock);
172759
172760 const shift_reg =
172761 try self.copyToTmpRegister(rhs_ty, .{ .air_ref = bin_op.rhs });
172762 const shift_lock = self.register_manager.lockRegAssumeUnused(shift_reg);
172763 defer self.register_manager.unlockReg(shift_lock);
172764
172765 const mask_ty = try pt.vectorType(.{ .len = 16, .child = .u8_type });
172766 const mask_mcv = try self.lowerValue(try pt.aggregateValue(
172767 mask_ty,
172768 &([1]InternPool.Index{
172769 (try rhs_ty.childType(zcu).maxIntScalar(pt, .u8)).toIntern(),
172770 } ++ [1]InternPool.Index{.zero_u8} ** 15),
172771 ));
172772 const mask_addr_reg = try self.copyToTmpRegister(.usize, mask_mcv.address());
172773 const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg);
172774 defer self.register_manager.unlockReg(mask_addr_lock);
172775
172776 if (self.hasFeature(.avx)) {
172777 try self.asmRegisterRegisterMemory(
172778 .{ .vp_, .@"and" },
172779 shift_reg.to128(),
172780 shift_reg.to128(),
172781 .{
172782 .base = .{ .reg = mask_addr_reg },
172783 .mod = .{ .rm = .{ .size = .xword } },
172784 },
172785 );
172786 try self.asmRegisterRegisterRegister(
172787 mir_tag,
172788 registerAlias(dst_reg, abi_size),
172789 registerAlias(lhs_reg, abi_size),
172790 shift_reg.to128(),
172791 );
172792 } else {
172793 try self.asmRegisterMemory(
172794 .{ .p_, .@"and" },
172795 shift_reg.to128(),
172796 .{
172797 .base = .{ .reg = mask_addr_reg },
172798 .mod = .{ .rm = .{ .size = .xword } },
172799 },
172800 );
172801 assert(dst_reg.id() == lhs_reg.id());
172802 try self.asmRegisterRegister(
172803 mir_tag,
172804 registerAlias(dst_reg, abi_size),
172805 shift_reg.to128(),
172806 );
172807 }
172808 break :result .{ .register = dst_reg };
172809 },
172810 else => {},
172811 },
172812 else => {},
172813 },
172814 else => {},
172815 }
172816 return self.fail("TODO implement airShlShrBinOp for {f}", .{lhs_ty.fmt(pt)});
172817 };
172818 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
172819}
172820
172821fn airShlSat(self: *CodeGen, inst: Air.Inst.Index) !void {
172822 const zcu = self.pt.zcu;
172823 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
172824 const lhs_ty = self.typeOf(bin_op.lhs);
172825 const rhs_ty = self.typeOf(bin_op.rhs);
172826
172827 const result: MCValue = result: {
172828 switch (lhs_ty.zigTypeTag(zcu)) {
172829 .int => {
172830 const lhs_bits = lhs_ty.bitSize(zcu);
172831 const rhs_bits = rhs_ty.bitSize(zcu);
172832 if (!(lhs_bits <= 32 and rhs_bits <= 5) and !(lhs_bits > 32 and lhs_bits <= 64 and rhs_bits <= 6) and !(rhs_bits <= std.math.log2(lhs_bits))) {
172833 return self.fail("TODO implement shl_sat for {} with lhs bits {}, rhs bits {}", .{ self.target.cpu.arch, lhs_bits, rhs_bits });
172834 }
172835
172836 // clobberred by genShiftBinOp
172837 try self.spillRegisters(&.{.rcx});
172838
172839 const lhs_mcv = try self.resolveInst(bin_op.lhs);
172840 var lhs_temp1 = try self.tempInit(lhs_ty, lhs_mcv);
172841 const rhs_mcv = try self.resolveInst(bin_op.rhs);
172842
172843 const lhs_lock = switch (lhs_mcv) {
172844 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
172845 else => null,
172846 };
172847 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
172848
172849 // shift left
172850 const dst_mcv = try self.genShiftBinOp(.shl, null, lhs_mcv, rhs_mcv, lhs_ty, rhs_ty);
172851 switch (dst_mcv) {
172852 .register => |dst_reg| try self.truncateRegister(lhs_ty, dst_reg),
172853 .register_pair => |dst_regs| try self.truncateRegister(lhs_ty, dst_regs[1]),
172854 .load_frame => |frame_addr| {
172855 const tmp_reg =
172856 try self.register_manager.allocReg(null, abi.RegisterClass.gp);
172857 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
172858 defer self.register_manager.unlockReg(tmp_lock);
172859
172860 const lhs_bits_u31: u31 = @intCast(lhs_bits);
172861 const tmp_ty: Type = if (lhs_bits_u31 > 64) .usize else lhs_ty;
172862 const off = frame_addr.off + (lhs_bits_u31 - 1) / 64 * 8;
172863 try self.genSetReg(
172864 tmp_reg,
172865 tmp_ty,
172866 .{ .load_frame = .{ .index = frame_addr.index, .off = off } },
172867 .{},
172868 );
172869 try self.truncateRegister(lhs_ty, tmp_reg);
172870 try self.genSetMem(
172871 .{ .frame = frame_addr.index },
172872 off,
172873 tmp_ty,
172874 .{ .register = tmp_reg },
172875 .{},
172876 );
172877 },
172878 else => {},
172879 }
172880 const dst_lock = switch (dst_mcv) {
172881 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
172882 else => null,
172883 };
172884 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
172885
172886 // shift right
172887 const tmp_mcv = try self.genShiftBinOp(.shr, null, dst_mcv, rhs_mcv, lhs_ty, rhs_ty);
172888 var tmp_temp = try self.tempInit(lhs_ty, tmp_mcv);
172889
172890 // check if overflow happens
172891 const cc_temp = lhs_temp1.cmpInts(.neq, &tmp_temp, self) catch |err| switch (err) {
172892 error.SelectFailed => unreachable,
172893 else => |e| return e,
172894 };
172895 try lhs_temp1.die(self);
172896 try tmp_temp.die(self);
172897 const overflow_reloc = try self.genCondBrMir(lhs_ty, cc_temp.tracking(self).short);
172898 try cc_temp.die(self);
172899
172900 // if overflow,
172901 // for unsigned integers, the saturating result is just its max
172902 // for signed integers,
172903 // if lhs is positive, the result is its max
172904 // if lhs is negative, it is min
172905 switch (lhs_ty.intInfo(zcu).signedness) {
172906 .unsigned => {
172907 const bound_mcv = try self.lowerValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));
172908 try self.genCopy(lhs_ty, dst_mcv, bound_mcv, .{});
172909 },
172910 .signed => {
172911 // check the sign of lhs
172912 // TODO: optimize this.
172913 // we only need the highest bit so shifting the highest part of lhs_mcv
172914 // is enough to check the signedness. other parts can be skipped here.
172915 var lhs_temp2 = try self.tempInit(lhs_ty, lhs_mcv);
172916 var zero_temp = try self.tempInit(lhs_ty, try self.lowerValue(try self.pt.intValue(lhs_ty, 0)));
172917 const sign_cc_temp = lhs_temp2.cmpInts(.lt, &zero_temp, self) catch |err| switch (err) {
172918 error.SelectFailed => unreachable,
172919 else => |e| return e,
172920 };
172921 try lhs_temp2.die(self);
172922 try zero_temp.die(self);
172923 const sign_reloc_condbr = try self.genCondBrMir(lhs_ty, sign_cc_temp.tracking(self).short);
172924 try sign_cc_temp.die(self);
172925
172926 // if it is negative
172927 const min_mcv = try self.lowerValue(try lhs_ty.minIntScalar(self.pt, lhs_ty));
172928 try self.genCopy(lhs_ty, dst_mcv, min_mcv, .{});
172929 const sign_reloc_br = try self.asmJmpReloc(undefined);
172930 self.performReloc(sign_reloc_condbr);
172931
172932 // if it is positive
172933 const max_mcv = try self.lowerValue(try lhs_ty.maxIntScalar(self.pt, lhs_ty));
172934 try self.genCopy(lhs_ty, dst_mcv, max_mcv, .{});
172935 self.performReloc(sign_reloc_br);
172936 },
172937 }
172938
172939 self.performReloc(overflow_reloc);
172940 break :result dst_mcv;
172941 },
172942 else => {
172943 return self.fail("TODO implement shl_sat for {} op type {}", .{ self.target.cpu.arch, lhs_ty.zigTypeTag(zcu) });
172944 },
172945 }
172946 };
172947 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
172948}
172949
172950fn airOptionalPayload(self: *CodeGen, inst: Air.Inst.Index) !void {
172951 const zcu = self.pt.zcu;
172952 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
172953 const result: MCValue = result: {
172954 const pl_ty = self.typeOfIndex(inst);
172955 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
172956
172957 const opt_mcv = try self.resolveInst(ty_op.operand);
172958 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
172959 const pl_mcv: MCValue = switch (opt_mcv) {
172960 .register_overflow => |ro| pl: {
172961 self.eflags_inst = null; // actually stop tracking the overflow part
172962 break :pl .{ .register = ro.reg };
172963 },
172964 else => opt_mcv,
172965 };
172966 switch (pl_mcv) {
172967 .register => |pl_reg| try self.truncateRegister(pl_ty, pl_reg),
172968 else => {},
172969 }
172970 break :result pl_mcv;
172971 }
172972
172973 const pl_mcv = try self.allocRegOrMem(inst, true);
172974 try self.genCopy(pl_ty, pl_mcv, switch (opt_mcv) {
172975 else => opt_mcv,
172976 .register_overflow => |ro| .{ .register = ro.reg },
172977 }, .{});
172978 break :result pl_mcv;
172979 };
172980 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
172981}
172982
172983fn airOptionalPayloadPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
172984 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
172985
172986 const dst_ty = self.typeOfIndex(inst);
172987 const opt_mcv = try self.resolveInst(ty_op.operand);
172988
172989 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
172990 opt_mcv
172991 else
172992 try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv);
172993 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
172994}
172995
172996fn airOptionalPayloadPtrSet(self: *CodeGen, inst: Air.Inst.Index) !void {
172997 const pt = self.pt;
172998 const zcu = pt.zcu;
172999 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173000 const result = result: {
173001 const dst_ty = self.typeOfIndex(inst);
173002 const src_ty = self.typeOf(ty_op.operand);
173003 const opt_ty = src_ty.childType(zcu);
173004 const src_mcv = try self.resolveInst(ty_op.operand);
173005
173006 if (opt_ty.optionalReprIsPayload(zcu)) {
173007 break :result if (self.liveness.isUnused(inst))
173008 .unreach
173009 else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
173010 src_mcv
173011 else
173012 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
173013 }
173014
173015 const dst_mcv: MCValue = if (src_mcv.isRegister() and
173016 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
173017 src_mcv
173018 else if (self.liveness.isUnused(inst))
173019 .{ .register = try self.copyToTmpRegister(dst_ty, src_mcv) }
173020 else
173021 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
173022
173023 const pl_ty = dst_ty.childType(zcu);
173024 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu));
173025 try self.genSetMem(
173026 .{ .reg = dst_mcv.getReg().? },
173027 pl_abi_size,
173028 .bool,
173029 .{ .immediate = 1 },
173030 .{},
173031 );
173032 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
173033 };
173034 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173035}
173036
173037fn airUnwrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void {
173038 const pt = self.pt;
173039 const zcu = pt.zcu;
173040 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173041 const err_union_ty = self.typeOf(ty_op.operand);
173042 const err_ty = err_union_ty.errorUnionSet(zcu);
173043 const payload_ty = err_union_ty.errorUnionPayload(zcu);
173044 const operand = try self.resolveInst(ty_op.operand);
173045
173046 const result: MCValue = result: {
173047 if (err_ty.errorSetIsEmpty(zcu)) {
173048 break :result MCValue{ .immediate = 0 };
173049 }
173050
173051 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
173052 break :result try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
173053 }
173054
173055 const err_off = codegen.errUnionErrorOffset(payload_ty, zcu);
173056 switch (operand) {
173057 .register => |reg| {
173058 // TODO reuse operand
173059 const eu_lock = self.register_manager.lockReg(reg);
173060 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
173061
173062 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
173063 if (err_off > 0) try self.genShiftBinOpMir(
173064 .{ ._r, .sh },
173065 err_union_ty,
173066 result,
173067 .u8,
173068 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
173069 ) else try self.truncateRegister(.anyerror, result.register);
173070 break :result result;
173071 },
173072 .load_frame => |frame_addr| break :result .{ .load_frame = .{
173073 .index = frame_addr.index,
173074 .off = frame_addr.off + @as(i32, @intCast(err_off)),
173075 } },
173076 else => return self.fail("TODO implement unwrap_err_err for {f}", .{operand}),
173077 }
173078 };
173079 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173080}
173081
173082fn airUnwrapErrUnionPayload(self: *CodeGen, inst: Air.Inst.Index) !void {
173083 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173084 const operand_ty = self.typeOf(ty_op.operand);
173085 const operand = try self.resolveInst(ty_op.operand);
173086 const result = try self.genUnwrapErrUnionPayloadMir(inst, operand_ty, operand);
173087 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173088}
173089
173090// *(E!T) -> E
173091fn airUnwrapErrUnionErrPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173092 const pt = self.pt;
173093 const zcu = pt.zcu;
173094 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173095
173096 const src_ty = self.typeOf(ty_op.operand);
173097 const src_mcv = try self.resolveInst(ty_op.operand);
173098 const src_reg = switch (src_mcv) {
173099 .register => |reg| reg,
173100 else => try self.copyToTmpRegister(src_ty, src_mcv),
173101 };
173102 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
173103 defer self.register_manager.unlockReg(src_lock);
173104
173105 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
173106 const dst_mcv = MCValue{ .register = dst_reg };
173107 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
173108 defer self.register_manager.unlockReg(dst_lock);
173109
173110 const eu_ty = src_ty.childType(zcu);
173111 const pl_ty = eu_ty.errorUnionPayload(zcu);
173112 const err_ty = eu_ty.errorUnionSet(zcu);
173113 const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu));
173114 const err_abi_size: u32 = @intCast(err_ty.abiSize(zcu));
173115 try self.asmRegisterMemory(
173116 .{ ._, .mov },
173117 registerAlias(dst_reg, err_abi_size),
173118 .{
173119 .base = .{ .reg = src_reg },
173120 .mod = .{ .rm = .{
173121 .size = .fromSize(err_abi_size),
173122 .disp = err_off,
173123 } },
173124 },
173125 );
173126
173127 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
173128}
173129
173130// *(E!T) -> *T
173131fn airUnwrapErrUnionPayloadPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173132 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173133 const operand_ty = self.typeOf(ty_op.operand);
173134 const operand = try self.resolveInst(ty_op.operand);
173135 const result = try self.genUnwrapErrUnionPayloadPtrMir(inst, operand_ty, operand);
173136 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173137}
173138
173139fn airErrUnionPayloadPtrSet(self: *CodeGen, inst: Air.Inst.Index) !void {
173140 const pt = self.pt;
173141 const zcu = pt.zcu;
173142 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173143 const result: MCValue = result: {
173144 const src_ty = self.typeOf(ty_op.operand);
173145 const src_mcv = try self.resolveInst(ty_op.operand);
173146 const src_reg = switch (src_mcv) {
173147 .register => |reg| reg,
173148 else => try self.copyToTmpRegister(src_ty, src_mcv),
173149 };
173150 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
173151 defer self.register_manager.unlockReg(src_lock);
173152
173153 const eu_ty = src_ty.childType(zcu);
173154 const pl_ty = eu_ty.errorUnionPayload(zcu);
173155 const err_ty = eu_ty.errorUnionSet(zcu);
173156 const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu));
173157 const err_abi_size: u32 = @intCast(err_ty.abiSize(zcu));
173158 try self.asmMemoryImmediate(
173159 .{ ._, .mov },
173160 .{
173161 .base = .{ .reg = src_reg },
173162 .mod = .{ .rm = .{
173163 .size = .fromSize(err_abi_size),
173164 .disp = err_off,
173165 } },
173166 },
173167 .u(0),
173168 );
173169
173170 if (self.liveness.isUnused(inst)) break :result .unreach;
173171
173172 const dst_ty = self.typeOfIndex(inst);
173173 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
173174 src_reg
173175 else
173176 try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
173177 const dst_lock = self.register_manager.lockReg(dst_reg);
173178 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
173179
173180 const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu));
173181 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(zcu));
173182 try self.asmRegisterMemory(
173183 .{ ._, .lea },
173184 registerAlias(dst_reg, dst_abi_size),
173185 .{
173186 .base = .{ .reg = src_reg },
173187 .mod = .{ .rm = .{ .disp = pl_off } },
173188 },
173189 );
173190 break :result .{ .register = dst_reg };
173191 };
173192 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173193}
173194
173195fn genUnwrapErrUnionPayloadMir(
173196 self: *CodeGen,
173197 maybe_inst: ?Air.Inst.Index,
173198 err_union_ty: Type,
173199 err_union: MCValue,
173200) !MCValue {
173201 const pt = self.pt;
173202 const zcu = pt.zcu;
173203 const payload_ty = err_union_ty.errorUnionPayload(zcu);
173204
173205 const result: MCValue = result: {
173206 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
173207
173208 const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
173209 switch (err_union) {
173210 .load_frame => |frame_addr| break :result .{ .load_frame = .{
173211 .index = frame_addr.index,
173212 .off = frame_addr.off + payload_off,
173213 } },
173214 .register => |reg| {
173215 // TODO reuse operand
173216 const eu_lock = self.register_manager.lockReg(reg);
173217 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
173218
173219 const payload_in_gp = self.regSetForType(payload_ty).supersetOf(abi.RegisterClass.gp);
173220 const result_mcv: MCValue = if (payload_in_gp and maybe_inst != null)
173221 try self.copyToRegisterWithInstTracking(maybe_inst.?, err_union_ty, err_union)
173222 else
173223 .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };
173224 if (payload_off > 0) try self.genShiftBinOpMir(
173225 .{ ._r, .sh },
173226 err_union_ty,
173227 result_mcv,
173228 .u8,
173229 .{ .immediate = @as(u6, @intCast(payload_off * 8)) },
173230 ) else try self.truncateRegister(payload_ty, result_mcv.register);
173231 break :result if (payload_in_gp)
173232 result_mcv
173233 else if (maybe_inst) |inst|
173234 try self.copyToRegisterWithInstTracking(inst, payload_ty, result_mcv)
173235 else
173236 .{ .register = try self.copyToTmpRegister(payload_ty, result_mcv) };
173237 },
173238 else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {f}", .{err_union}),
173239 }
173240 };
173241
173242 return result;
173243}
173244
173245fn genUnwrapErrUnionPayloadPtrMir(
173246 self: *CodeGen,
173247 maybe_inst: ?Air.Inst.Index,
173248 ptr_ty: Type,
173249 ptr_mcv: MCValue,
173250) !MCValue {
173251 const pt = self.pt;
173252 const zcu = pt.zcu;
173253 const err_union_ty = ptr_ty.childType(zcu);
173254 const payload_ty = err_union_ty.errorUnionPayload(zcu);
173255
173256 const result: MCValue = result: {
173257 const payload_off = codegen.errUnionPayloadOffset(payload_ty, zcu);
173258 const result_mcv: MCValue = if (maybe_inst) |inst|
173259 try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv)
173260 else
173261 .{ .register = try self.copyToTmpRegister(ptr_ty, ptr_mcv) };
173262 try self.genBinOpMir(.{ ._, .add }, ptr_ty, result_mcv, .{ .immediate = payload_off });
173263 break :result result_mcv;
173264 };
173265
173266 return result;
173267}
173268
173269fn airWrapOptional(self: *CodeGen, inst: Air.Inst.Index) !void {
173270 const pt = self.pt;
173271 const zcu = pt.zcu;
173272 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173273 const result: MCValue = result: {
173274 const pl_ty = self.typeOf(ty_op.operand);
173275 if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 };
173276
173277 const opt_ty = self.typeOfIndex(inst);
173278 const pl_mcv = try self.resolveInst(ty_op.operand);
173279 const same_repr = opt_ty.optionalReprIsPayload(zcu);
173280 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
173281
173282 const pl_lock: ?RegisterLock = switch (pl_mcv) {
173283 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173284 else => null,
173285 };
173286 defer if (pl_lock) |lock| self.register_manager.unlockReg(lock);
173287
173288 const opt_mcv = try self.allocRegOrMem(inst, true);
173289 try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{});
173290
173291 if (!same_repr) {
173292 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu));
173293 switch (opt_mcv) {
173294 else => unreachable,
173295
173296 .register => |opt_reg| {
173297 try self.truncateRegister(pl_ty, opt_reg);
173298 try self.asmRegisterImmediate(
173299 .{ ._s, .bt },
173300 opt_reg,
173301 .u(@as(u6, @intCast(pl_abi_size * 8))),
173302 );
173303 },
173304
173305 .load_frame => |frame_addr| try self.asmMemoryImmediate(
173306 .{ ._, .mov },
173307 .{
173308 .base = .{ .frame = frame_addr.index },
173309 .mod = .{ .rm = .{
173310 .size = .byte,
173311 .disp = frame_addr.off + pl_abi_size,
173312 } },
173313 },
173314 .u(1),
173315 ),
173316 }
173317 }
173318 break :result opt_mcv;
173319 };
173320 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173321}
173322
173323/// T to E!T
173324fn airWrapErrUnionPayload(self: *CodeGen, inst: Air.Inst.Index) !void {
173325 const pt = self.pt;
173326 const zcu = pt.zcu;
173327 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173328
173329 const eu_ty = ty_op.ty.toType();
173330 const pl_ty = eu_ty.errorUnionPayload(zcu);
173331 const err_ty = eu_ty.errorUnionSet(zcu);
173332 const operand = try self.resolveInst(ty_op.operand);
173333
173334 const result: MCValue = result: {
173335 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 };
173336
173337 const frame_index = try self.allocFrameIndex(.initSpill(eu_ty, zcu));
173338 const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu));
173339 const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu));
173340 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{});
173341 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{});
173342 break :result .{ .load_frame = .{ .index = frame_index } };
173343 };
173344 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173345}
173346
173347/// E to E!T
173348fn airWrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void {
173349 const pt = self.pt;
173350 const zcu = pt.zcu;
173351 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173352
173353 const eu_ty = ty_op.ty.toType();
173354 const pl_ty = eu_ty.errorUnionPayload(zcu);
173355 const err_ty = eu_ty.errorUnionSet(zcu);
173356
173357 const result: MCValue = result: {
173358 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try self.resolveInst(ty_op.operand);
173359
173360 const frame_index = try self.allocFrameIndex(.initSpill(eu_ty, zcu));
173361 const pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(pl_ty, zcu));
173362 const err_off: i32 = @intCast(codegen.errUnionErrorOffset(pl_ty, zcu));
173363 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{});
173364 const operand = try self.resolveInst(ty_op.operand);
173365 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{});
173366 break :result .{ .load_frame = .{ .index = frame_index } };
173367 };
173368 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173369}
173370
173371fn airSlicePtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173372 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173373 const result = result: {
173374 const src_mcv = try self.resolveInst(ty_op.operand);
173375 const ptr_mcv: MCValue = switch (src_mcv) {
173376 .register_pair => |regs| .{ .register = regs[0] },
173377 else => src_mcv,
173378 };
173379 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) {
173380 switch (src_mcv) {
173381 .register_pair => |regs| try self.freeValue(.{ .register = regs[1] }),
173382 else => {},
173383 }
173384 break :result ptr_mcv;
173385 }
173386
173387 const dst_mcv = try self.allocRegOrMem(inst, true);
173388 try self.genCopy(self.typeOfIndex(inst), dst_mcv, ptr_mcv, .{});
173389 break :result dst_mcv;
173390 };
173391 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173392}
173393
173394fn airSliceLen(self: *CodeGen, inst: Air.Inst.Index) !void {
173395 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173396 const result = result: {
173397 const src_mcv = try self.resolveInst(ty_op.operand);
173398 const len_mcv: MCValue = switch (src_mcv) {
173399 .register_pair => |regs| .{ .register = regs[1] },
173400 .load_frame => |frame_addr| .{ .load_frame = .{
173401 .index = frame_addr.index,
173402 .off = frame_addr.off + 8,
173403 } },
173404 else => return self.fail("TODO implement slice_len for {f}", .{src_mcv}),
173405 };
173406 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) {
173407 switch (src_mcv) {
173408 .register_pair => |regs| try self.freeValue(.{ .register = regs[0] }),
173409 .load_frame => {},
173410 else => unreachable,
173411 }
173412 break :result len_mcv;
173413 }
173414
173415 const dst_mcv = try self.allocRegOrMem(inst, true);
173416 try self.genCopy(self.typeOfIndex(inst), dst_mcv, len_mcv, .{});
173417 break :result dst_mcv;
173418 };
173419 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
173420}
173421
173422fn airPtrSliceLenPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173423 const pt = self.pt;
173424 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173425
173426 const src_ty = self.typeOf(ty_op.operand);
173427 const src_mcv = try self.resolveInst(ty_op.operand);
173428 const src_reg = switch (src_mcv) {
173429 .register => |reg| reg,
173430 else => try self.copyToTmpRegister(src_ty, src_mcv),
173431 };
173432 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
173433 defer self.register_manager.unlockReg(src_lock);
173434
173435 const dst_ty = self.typeOfIndex(inst);
173436 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
173437 src_reg
173438 else
173439 try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
173440 const dst_mcv = MCValue{ .register = dst_reg };
173441 const dst_lock = self.register_manager.lockReg(dst_reg);
173442 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
173443
173444 const dst_abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu));
173445 try self.asmRegisterMemory(
173446 .{ ._, .lea },
173447 registerAlias(dst_reg, dst_abi_size),
173448 .{
173449 .base = .{ .reg = src_reg },
173450 .mod = .{ .rm = .{ .disp = 8 } },
173451 },
173452 );
173453
173454 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
173455}
173456
173457fn airPtrSlicePtrPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173458 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173459
173460 const dst_ty = self.typeOfIndex(inst);
173461 const opt_mcv = try self.resolveInst(ty_op.operand);
173462
173463 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
173464 opt_mcv
173465 else
173466 try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv);
173467 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
173468}
173469
173470fn elemOffset(self: *CodeGen, index_ty: Type, index: MCValue, elem_size: u64) !Register {
173471 const reg: Register = blk: {
173472 switch (index) {
173473 .immediate => |imm| {
173474 // Optimisation: if index MCValue is an immediate, we can multiply in `comptime`
173475 // and set the register directly to the scaled offset as an immediate.
173476 const reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
173477 try self.genSetReg(reg, index_ty, .{ .immediate = imm * elem_size }, .{});
173478 break :blk reg;
173479 },
173480 else => {
173481 const reg = try self.copyToTmpRegister(index_ty, index);
173482 try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size });
173483 break :blk reg;
173484 },
173485 }
173486 };
173487 return reg;
173488}
173489
173490fn genSliceElemPtr(self: *CodeGen, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
173491 const pt = self.pt;
173492 const zcu = pt.zcu;
173493 const slice_ty = self.typeOf(lhs);
173494 const slice_mcv = try self.resolveInst(lhs);
173495 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
173496 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173497 else => null,
173498 };
173499 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);
173500
173501 const elem_ty = slice_ty.childType(zcu);
173502 const elem_size = elem_ty.abiSize(zcu);
173503 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
173504
173505 const index_ty = self.typeOf(rhs);
173506 const index_mcv = try self.resolveInst(rhs);
173507 const index_mcv_lock: ?RegisterLock = switch (index_mcv) {
173508 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173509 else => null,
173510 };
173511 defer if (index_mcv_lock) |lock| self.register_manager.unlockReg(lock);
173512
173513 const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_size);
173514 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
173515 defer self.register_manager.unlockReg(offset_reg_lock);
173516
173517 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
173518 try self.genSetReg(addr_reg, .usize, slice_mcv, .{});
173519 // TODO we could allocate register here, but need to expect addr register and potentially
173520 // offset register.
173521 try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{
173522 .register = offset_reg,
173523 });
173524 return MCValue{ .register = addr_reg.to64() };
173525}
173526
173527fn airSliceElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
173528 const pt = self.pt;
173529 const zcu = pt.zcu;
173530 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
173531
173532 const result: MCValue = result: {
173533 const elem_ty = self.typeOfIndex(inst);
173534 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
173535
173536 const slice_ty = self.typeOf(bin_op.lhs);
173537 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
173538 const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
173539 const dst_mcv = try self.allocRegOrMem(inst, false);
173540 try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);
173541 break :result dst_mcv;
173542 };
173543 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
173544}
173545
173546fn airSliceElemPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173547 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
173548 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
173549 const dst_mcv = try self.genSliceElemPtr(extra.lhs, extra.rhs);
173550 return self.finishAir(inst, dst_mcv, .{ extra.lhs, extra.rhs, .none });
173551}
173552
173553fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
173554 const pt = self.pt;
173555 const zcu = pt.zcu;
173556 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
173557
173558 const result: MCValue = result: {
173559 const array_ty = self.typeOf(bin_op.lhs);
173560 const elem_ty = array_ty.childType(zcu);
173561
173562 const array_mcv = try self.resolveInst(bin_op.lhs);
173563 const array_lock: ?RegisterLock = switch (array_mcv) {
173564 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173565 else => null,
173566 };
173567 defer if (array_lock) |lock| self.register_manager.unlockReg(lock);
173568
173569 const index_ty = self.typeOf(bin_op.rhs);
173570 const index_mcv = try self.resolveInst(bin_op.rhs);
173571 const index_lock = switch (index_mcv) {
173572 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173573 else => null,
173574 };
173575 defer if (index_lock) |lock| self.register_manager.unlockReg(lock);
173576
173577 try self.spillEflagsIfOccupied();
173578 if (array_ty.isVector(zcu) and elem_ty.bitSize(zcu) == 1) {
173579 const array_mat_mcv: MCValue = switch (array_mcv) {
173580 else => array_mcv,
173581 .register_mask => .{ .register = try self.copyToTmpRegister(array_ty, array_mcv) },
173582 };
173583 const array_mat_lock = switch (array_mat_mcv) {
173584 .register => |reg| self.register_manager.lockReg(reg),
173585 else => null,
173586 };
173587 defer if (array_mat_lock) |lock| self.register_manager.unlockReg(lock);
173588
173589 switch (array_mat_mcv) {
173590 .register => |array_reg| switch (array_reg.class()) {
173591 .general_purpose => switch (index_mcv) {
173592 .immediate => |index_imm| try self.asmRegisterImmediate(
173593 .{ ._, .bt },
173594 array_reg.to64(),
173595 .u(index_imm),
173596 ),
173597 else => try self.asmRegisterRegister(
173598 .{ ._, .bt },
173599 array_reg.to64(),
173600 switch (index_mcv) {
173601 .register => |index_reg| index_reg,
173602 else => try self.copyToTmpRegister(index_ty, index_mcv),
173603 }.to64(),
173604 ),
173605 },
173606 .sse => {
173607 const frame_index = try self.allocFrameIndex(.initType(array_ty, zcu));
173608 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mat_mcv, .{});
173609 switch (index_mcv) {
173610 .immediate => |index_imm| try self.asmMemoryImmediate(
173611 .{ ._, .bt },
173612 .{
173613 .base = .{ .frame = frame_index },
173614 .mod = .{ .rm = .{
173615 .size = .qword,
173616 .disp = @intCast(index_imm / 64 * 8),
173617 } },
173618 },
173619 .u(index_imm % 64),
173620 ),
173621 else => try self.asmMemoryRegister(
173622 .{ ._, .bt },
173623 .{
173624 .base = .{ .frame = frame_index },
173625 .mod = .{ .rm = .{ .size = .qword } },
173626 },
173627 switch (index_mcv) {
173628 .register => |index_reg| index_reg,
173629 else => try self.copyToTmpRegister(index_ty, index_mcv),
173630 }.to64(),
173631 ),
173632 }
173633 },
173634 else => unreachable,
173635 },
173636 .load_frame => switch (index_mcv) {
173637 .immediate => |index_imm| try self.asmMemoryImmediate(
173638 .{ ._, .bt },
173639 try array_mat_mcv.mem(self, .{
173640 .size = .qword,
173641 .disp = @intCast(index_imm / 64 * 8),
173642 }),
173643 .u(index_imm % 64),
173644 ),
173645 else => try self.asmMemoryRegister(
173646 .{ ._, .bt },
173647 try array_mat_mcv.mem(self, .{ .size = .qword }),
173648 switch (index_mcv) {
173649 .register => |index_reg| index_reg,
173650 else => try self.copyToTmpRegister(index_ty, index_mcv),
173651 }.to64(),
173652 ),
173653 },
173654 .memory,
173655 .load_nav,
173656 .load_uav,
173657 .load_lazy_sym,
173658 .load_extern_func,
173659 => switch (index_mcv) {
173660 .immediate => |index_imm| try self.asmMemoryImmediate(
173661 .{ ._, .bt },
173662 .{
173663 .base = .{
173664 .reg = try self.copyToTmpRegister(.usize, array_mat_mcv.address()),
173665 },
173666 .mod = .{ .rm = .{
173667 .size = .qword,
173668 .disp = @intCast(index_imm / 64 * 8),
173669 } },
173670 },
173671 .u(index_imm % 64),
173672 ),
173673 else => try self.asmMemoryRegister(
173674 .{ ._, .bt },
173675 .{
173676 .base = .{
173677 .reg = try self.copyToTmpRegister(.usize, array_mat_mcv.address()),
173678 },
173679 .mod = .{ .rm = .{ .size = .qword } },
173680 },
173681 switch (index_mcv) {
173682 .register => |index_reg| index_reg,
173683 else => try self.copyToTmpRegister(index_ty, index_mcv),
173684 }.to64(),
173685 ),
173686 },
173687 else => return self.fail("TODO airArrayElemVal for {s} of {f}", .{
173688 @tagName(array_mat_mcv), array_ty.fmt(pt),
173689 }),
173690 }
173691
173692 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
173693 try self.asmSetccRegister(.c, dst_reg.to8());
173694 break :result .{ .register = dst_reg };
173695 }
173696
173697 const elem_abi_size = elem_ty.abiSize(zcu);
173698 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
173699 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
173700 defer self.register_manager.unlockReg(addr_lock);
173701
173702 switch (array_mcv) {
173703 .register => {
173704 const frame_index = try self.allocFrameIndex(.initType(array_ty, zcu));
173705 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{});
173706 try self.asmRegisterMemory(
173707 .{ ._, .lea },
173708 addr_reg,
173709 .{ .base = .{ .frame = frame_index } },
173710 );
173711 },
173712 .load_frame => |frame_addr| try self.asmRegisterMemory(
173713 .{ ._, .lea },
173714 addr_reg,
173715 .{
173716 .base = .{ .frame = frame_addr.index },
173717 .mod = .{ .rm = .{ .disp = frame_addr.off } },
173718 },
173719 ),
173720 .memory,
173721 .load_nav,
173722 .lea_nav,
173723 .load_uav,
173724 .lea_uav,
173725 .load_lazy_sym,
173726 .lea_lazy_sym,
173727 .load_extern_func,
173728 .lea_extern_func,
173729 => try self.genSetReg(addr_reg, .usize, array_mcv.address(), .{}),
173730 else => return self.fail("TODO airArrayElemVal_val for {s} of {f}", .{
173731 @tagName(array_mcv), array_ty.fmt(pt),
173732 }),
173733 }
173734
173735 const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size);
173736 const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
173737 defer self.register_manager.unlockReg(offset_lock);
173738
173739 // TODO we could allocate register here, but need to expect addr register and potentially
173740 // offset register.
173741 const dst_mcv = try self.allocRegOrMem(inst, false);
173742 try self.genBinOpMir(.{ ._, .add }, .usize, .{ .register = addr_reg }, .{ .register = offset_reg });
173743 try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{});
173744 break :result dst_mcv;
173745 };
173746 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
173747}
173748
173749fn airPtrElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
173750 const pt = self.pt;
173751 const zcu = pt.zcu;
173752 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
173753 const ptr_ty = self.typeOf(bin_op.lhs);
173754
173755 // this is identical to the `airPtrElemPtr` codegen expect here an
173756 // additional `mov` is needed at the end to get the actual value
173757
173758 const result = result: {
173759 const elem_ty = ptr_ty.elemType2(zcu);
173760 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
173761
173762 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu));
173763 const index_ty = self.typeOf(bin_op.rhs);
173764 const index_mcv = try self.resolveInst(bin_op.rhs);
173765 const index_lock = switch (index_mcv) {
173766 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173767 else => null,
173768 };
173769 defer if (index_lock) |lock| self.register_manager.unlockReg(lock);
173770
173771 const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size);
173772 const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
173773 defer self.register_manager.unlockReg(offset_lock);
173774
173775 const ptr_mcv = try self.resolveInst(bin_op.lhs);
173776 const elem_ptr_reg = if (ptr_mcv.isRegister() and self.liveness.operandDies(inst, 0))
173777 ptr_mcv.register
173778 else
173779 try self.copyToTmpRegister(ptr_ty, ptr_mcv);
173780 const elem_ptr_lock = self.register_manager.lockRegAssumeUnused(elem_ptr_reg);
173781 defer self.register_manager.unlockReg(elem_ptr_lock);
173782 try self.asmRegisterRegister(
173783 .{ ._, .add },
173784 elem_ptr_reg,
173785 offset_reg,
173786 );
173787
173788 const dst_mcv = try self.allocRegOrMem(inst, true);
173789 const dst_lock = switch (dst_mcv) {
173790 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173791 else => null,
173792 };
173793 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
173794 try self.load(dst_mcv, ptr_ty, .{ .register = elem_ptr_reg });
173795 break :result dst_mcv;
173796 };
173797 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
173798}
173799
173800fn airPtrElemPtr(self: *CodeGen, inst: Air.Inst.Index) !void {
173801 const pt = self.pt;
173802 const zcu = pt.zcu;
173803 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
173804 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
173805
173806 const result = result: {
173807 const elem_ptr_ty = self.typeOfIndex(inst);
173808 const base_ptr_ty = self.typeOf(extra.lhs);
173809
173810 const base_ptr_mcv = try self.resolveInst(extra.lhs);
173811 const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) {
173812 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173813 else => null,
173814 };
173815 defer if (base_ptr_lock) |lock| self.register_manager.unlockReg(lock);
173816
173817 if (elem_ptr_ty.ptrInfo(zcu).flags.vector_index != .none) {
173818 break :result if (self.reuseOperand(inst, extra.lhs, 0, base_ptr_mcv))
173819 base_ptr_mcv
173820 else
173821 try self.copyToRegisterWithInstTracking(inst, elem_ptr_ty, base_ptr_mcv);
173822 }
173823
173824 const elem_ty = base_ptr_ty.elemType2(zcu);
173825 const elem_abi_size = elem_ty.abiSize(zcu);
173826 const index_ty = self.typeOf(extra.rhs);
173827 const index_mcv = try self.resolveInst(extra.rhs);
173828 const index_lock: ?RegisterLock = switch (index_mcv) {
173829 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173830 else => null,
173831 };
173832 defer if (index_lock) |lock| self.register_manager.unlockReg(lock);
173833
173834 const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size);
173835 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
173836 defer self.register_manager.unlockReg(offset_reg_lock);
173837
173838 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, elem_ptr_ty, base_ptr_mcv);
173839 try self.genBinOpMir(.{ ._, .add }, elem_ptr_ty, dst_mcv, .{ .register = offset_reg });
173840
173841 break :result dst_mcv;
173842 };
173843 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
173844}
173845
173846fn airSetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void {
173847 const pt = self.pt;
173848 const zcu = pt.zcu;
173849 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
173850 const ptr_union_ty = self.typeOf(bin_op.lhs);
173851 const union_ty = ptr_union_ty.childType(zcu);
173852 const tag_ty = self.typeOf(bin_op.rhs);
173853 const layout = union_ty.unionGetLayout(zcu);
173854
173855 if (layout.tag_size == 0) {
173856 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
173857 }
173858
173859 const ptr = try self.resolveInst(bin_op.lhs);
173860 const ptr_lock: ?RegisterLock = switch (ptr) {
173861 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173862 else => null,
173863 };
173864 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
173865
173866 const tag = try self.resolveInst(bin_op.rhs);
173867 const tag_lock: ?RegisterLock = switch (tag) {
173868 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173869 else => null,
173870 };
173871 defer if (tag_lock) |lock| self.register_manager.unlockReg(lock);
173872
173873 const adjusted_ptr: MCValue = if (layout.payload_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) blk: {
173874 // TODO reusing the operand
173875 const reg = try self.copyToTmpRegister(ptr_union_ty, ptr);
173876 try self.genBinOpMir(
173877 .{ ._, .add },
173878 ptr_union_ty,
173879 .{ .register = reg },
173880 .{ .immediate = layout.payload_size },
173881 );
173882 break :blk MCValue{ .register = reg };
173883 } else ptr;
173884
173885 const ptr_tag_ty = try pt.adjustPtrTypeChild(ptr_union_ty, tag_ty);
173886 try self.store(ptr_tag_ty, adjusted_ptr, tag, .{});
173887
173888 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
173889}
173890
173891fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void {
173892 const zcu = self.pt.zcu;
173893 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173894
173895 const tag_ty = self.typeOfIndex(inst);
173896 const union_ty = self.typeOf(ty_op.operand);
173897 const layout = union_ty.unionGetLayout(zcu);
173898
173899 if (layout.tag_size == 0) {
173900 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });
173901 }
173902
173903 // TODO reusing the operand
173904 const operand = try self.resolveInst(ty_op.operand);
173905 const operand_lock: ?RegisterLock = switch (operand) {
173906 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
173907 else => null,
173908 };
173909 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
173910
173911 const tag_abi_size = tag_ty.abiSize(zcu);
173912 const dst_mcv: MCValue = blk: {
173913 switch (operand) {
173914 .load_frame => |frame_addr| {
173915 if (tag_abi_size <= 8) {
173916 const off: i32 = @intCast(layout.tagOffset());
173917 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
173918 .load_frame = .{ .index = frame_addr.index, .off = frame_addr.off + off },
173919 });
173920 }
173921
173922 return self.fail(
173923 "TODO implement get_union_tag for ABI larger than 8 bytes and operand {f}",
173924 .{operand},
173925 );
173926 },
173927 .register => {
173928 const shift: u6 = @intCast(layout.tagOffset() * 8);
173929 const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);
173930 try self.genShiftBinOpMir(.{ ._r, .sh }, .usize, result, .u8, .{ .immediate = shift });
173931 break :blk MCValue{
173932 .register = registerAlias(result.register, @intCast(layout.tag_size)),
173933 };
173934 },
173935 else => return self.fail("TODO implement get_union_tag for {f}", .{operand}),
173936 }
173937 };
173938
173939 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
173940}
173941
173942fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void {
173943 const pt = self.pt;
173944 const zcu = pt.zcu;
173945 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
173946 const result = result: {
173947 try self.spillEflagsIfOccupied();
173948
173949 const dst_ty = self.typeOfIndex(inst);
173950 const src_ty = self.typeOf(ty_op.operand);
173951 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airClz for {f}", .{
173952 src_ty.fmt(pt),
173953 });
173954
173955 const src_mcv = try self.resolveInst(ty_op.operand);
173956 const mat_src_mcv = switch (src_mcv) {
173957 .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) },
173958 else => src_mcv,
173959 };
173960 const mat_src_lock = switch (mat_src_mcv) {
173961 .register => |reg| self.register_manager.lockReg(reg),
173962 else => null,
173963 };
173964 defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock);
173965
173966 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
173967 const dst_mcv = MCValue{ .register = dst_reg };
173968 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
173969 defer self.register_manager.unlockReg(dst_lock);
173970
173971 const abi_size: u31 = @intCast(src_ty.abiSize(zcu));
173972 const src_bits: u31 = @intCast(src_ty.bitSize(zcu));
173973 const has_lzcnt = self.hasFeature(.lzcnt);
173974 if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) {
173975 const src_frame_addr: bits.FrameAddr = src_frame_addr: switch (src_mcv) {
173976 .load_frame => |src_frame_addr| src_frame_addr,
173977 else => {
173978 const src_frame_addr = try self.allocFrameIndex(.initSpill(src_ty, zcu));
173979 try self.genSetMem(.{ .frame = src_frame_addr }, 0, src_ty, src_mcv, .{});
173980 break :src_frame_addr .{ .index = src_frame_addr };
173981 },
173982 };
173983
173984 const limbs_len = std.math.divCeil(u32, abi_size, 8) catch unreachable;
173985 const extra_bits = abi_size * 8 - src_bits;
173986
173987 const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
173988 const index_lock = self.register_manager.lockRegAssumeUnused(index_reg);
173989 defer self.register_manager.unlockReg(index_lock);
173990
173991 try self.asmRegisterImmediate(.{ ._, .mov }, index_reg.to32(), .u(limbs_len));
173992 switch (extra_bits) {
173993 1 => try self.asmRegisterRegister(.{ ._, .xor }, dst_reg.to32(), dst_reg.to32()),
173994 else => try self.asmRegisterImmediate(
173995 .{ ._, .mov },
173996 dst_reg.to32(),
173997 .s(@as(i32, extra_bits) - 1),
173998 ),
173999 }
174000 const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
174001 try self.asmRegisterRegister(.{ ._, .@"test" }, index_reg.to32(), index_reg.to32());
174002 const zero = try self.asmJccReloc(.z, undefined);
174003 if (self.hasFeature(.slow_incdec)) {
174004 try self.asmRegisterImmediate(.{ ._, .sub }, index_reg.to32(), .u(1));
174005 } else {
174006 try self.asmRegister(.{ ._c, .de }, index_reg.to32());
174007 }
174008 try self.asmMemoryImmediate(.{ ._, .cmp }, .{
174009 .base = .{ .frame = src_frame_addr.index },
174010 .mod = .{ .rm = .{
174011 .size = .qword,
174012 .index = index_reg.to64(),
174013 .scale = .@"8",
174014 .disp = src_frame_addr.off,
174015 } },
174016 }, .u(0));
174017 _ = try self.asmJccReloc(.e, loop);
174018 try self.asmRegisterMemory(.{ ._r, .bs }, dst_reg.to64(), .{
174019 .base = .{ .frame = src_frame_addr.index },
174020 .mod = .{ .rm = .{
174021 .size = .qword,
174022 .index = index_reg.to64(),
174023 .scale = .@"8",
174024 .disp = src_frame_addr.off,
174025 } },
174026 });
174027 self.performReloc(zero);
174028 try self.asmRegisterImmediate(.{ ._l, .sh }, index_reg.to32(), .u(6));
174029 try self.asmRegisterRegister(.{ ._, .add }, index_reg.to32(), dst_reg.to32());
174030 try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to32(), .u(src_bits - 1));
174031 try self.asmRegisterRegister(.{ ._, .sub }, dst_reg.to32(), index_reg.to32());
174032 break :result dst_mcv;
174033 }
174034
174035 if (has_lzcnt) {
174036 if (src_bits <= 8) {
174037 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
174038 try self.truncateRegister(src_ty, wide_reg);
174039 try self.genBinOpMir(.{ ._, .lzcnt }, .u32, dst_mcv, .{ .register = wide_reg });
174040 try self.genBinOpMir(
174041 .{ ._, .sub },
174042 dst_ty,
174043 dst_mcv,
174044 .{ .immediate = 32 - src_bits },
174045 );
174046 } else if (src_bits <= 64) {
174047 try self.genBinOpMir(.{ ._, .lzcnt }, src_ty, dst_mcv, mat_src_mcv);
174048 const extra_bits = self.regExtraBits(src_ty);
174049 if (extra_bits > 0) {
174050 try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .immediate = extra_bits });
174051 }
174052 } else {
174053 assert(src_bits <= 128);
174054 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
174055 const tmp_mcv = MCValue{ .register = tmp_reg };
174056 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
174057 defer self.register_manager.unlockReg(tmp_lock);
174058
174059 try self.genBinOpMir(.{ ._, .lzcnt }, .u64, dst_mcv, if (mat_src_mcv.isBase())
174060 mat_src_mcv
174061 else
174062 .{ .register = mat_src_mcv.register_pair[0] });
174063 try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 });
174064 try self.genBinOpMir(.{ ._, .lzcnt }, .u64, tmp_mcv, if (mat_src_mcv.isBase())
174065 mat_src_mcv.address().offset(8).deref()
174066 else
174067 .{ .register = mat_src_mcv.register_pair[1] });
174068 try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32());
174069
174070 if (src_bits < 128) try self.genBinOpMir(
174071 .{ ._, .sub },
174072 dst_ty,
174073 dst_mcv,
174074 .{ .immediate = 128 - src_bits },
174075 );
174076 }
174077 break :result dst_mcv;
174078 }
174079
174080 assert(src_bits <= 64);
174081 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(zcu))), 2);
174082 if (std.math.isPowerOfTwo(src_bits)) {
174083 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
174084 .immediate = src_bits ^ (src_bits - 1),
174085 });
174086 const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg);
174087 defer self.register_manager.unlockReg(imm_lock);
174088
174089 if (src_bits <= 8) {
174090 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
174091 const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg);
174092 defer self.register_manager.unlockReg(wide_lock);
174093
174094 try self.truncateRegister(src_ty, wide_reg);
174095 try self.genBinOpMir(.{ ._r, .bs }, .u16, dst_mcv, .{ .register = wide_reg });
174096 } else try self.genBinOpMir(.{ ._r, .bs }, src_ty, dst_mcv, mat_src_mcv);
174097
174098 try self.asmCmovccRegisterRegister(
174099 .z,
174100 registerAlias(dst_reg, cmov_abi_size),
174101 registerAlias(imm_reg, cmov_abi_size),
174102 );
174103
174104 try self.genBinOpMir(.{ ._, .xor }, dst_ty, dst_mcv, .{ .immediate = src_bits - 1 });
174105 } else {
174106 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
174107 .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - self.regBitSize(dst_ty)),
174108 });
174109 const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg);
174110 defer self.register_manager.unlockReg(imm_lock);
174111
174112 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
174113 const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg);
174114 defer self.register_manager.unlockReg(wide_lock);
174115
174116 try self.truncateRegister(src_ty, wide_reg);
174117 try self.genBinOpMir(
174118 .{ ._r, .bs },
174119 if (src_bits <= 8) .u16 else src_ty,
174120 dst_mcv,
174121 .{ .register = wide_reg },
174122 );
174123
174124 try self.asmCmovccRegisterRegister(
174125 .nz,
174126 registerAlias(imm_reg, cmov_abi_size),
174127 registerAlias(dst_reg, cmov_abi_size),
174128 );
174129
174130 try self.genSetReg(dst_reg, dst_ty, .{ .immediate = src_bits - 1 }, .{});
174131 try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .register = imm_reg });
174132 }
174133 break :result dst_mcv;
174134 };
174135 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
174136}
174137
174138fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void {
174139 const pt = self.pt;
174140 const zcu = pt.zcu;
174141 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
174142 const result = result: {
174143 try self.spillEflagsIfOccupied();
174144
174145 const dst_ty = self.typeOfIndex(inst);
174146 const src_ty = self.typeOf(ty_op.operand);
174147 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airCtz for {f}", .{
174148 src_ty.fmt(pt),
174149 });
174150
174151 const src_mcv = try self.resolveInst(ty_op.operand);
174152 const mat_src_mcv = switch (src_mcv) {
174153 .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) },
174154 else => src_mcv,
174155 };
174156 const mat_src_lock = switch (mat_src_mcv) {
174157 .register => |reg| self.register_manager.lockReg(reg),
174158 else => null,
174159 };
174160 defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock);
174161
174162 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
174163 const dst_mcv = MCValue{ .register = dst_reg };
174164 const dst_lock = self.register_manager.lockReg(dst_reg);
174165 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
174166
174167 const abi_size: u31 = @intCast(src_ty.abiSize(zcu));
174168 const src_bits: u31 = @intCast(src_ty.bitSize(zcu));
174169 const has_bmi = self.hasFeature(.bmi);
174170 if (src_bits > @as(u32, if (has_bmi) 128 else 64)) {
174171 const src_frame_addr: bits.FrameAddr = src_frame_addr: switch (src_mcv) {
174172 .load_frame => |src_frame_addr| src_frame_addr,
174173 else => {
174174 const src_frame_addr = try self.allocFrameIndex(.initSpill(src_ty, zcu));
174175 try self.genSetMem(.{ .frame = src_frame_addr }, 0, src_ty, src_mcv, .{});
174176 break :src_frame_addr .{ .index = src_frame_addr };
174177 },
174178 };
174179
174180 const limbs_len = std.math.divCeil(u32, abi_size, 8) catch unreachable;
174181 const extra_bits = abi_size * 8 - src_bits;
174182
174183 const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
174184 const index_lock = self.register_manager.lockRegAssumeUnused(index_reg);
174185 defer self.register_manager.unlockReg(index_lock);
174186
174187 try self.asmRegisterImmediate(.{ ._, .mov }, index_reg.to32(), .s(-1));
174188 switch (extra_bits) {
174189 0 => try self.asmRegisterRegister(.{ ._, .xor }, dst_reg.to32(), dst_reg.to32()),
174190 1 => try self.asmRegisterRegister(.{ ._, .mov }, dst_reg.to32(), dst_reg.to32()),
174191 else => try self.asmRegisterImmediate(
174192 .{ ._, .mov },
174193 dst_reg.to32(),
174194 .s(-@as(i32, extra_bits)),
174195 ),
174196 }
174197 const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
174198 if (self.hasFeature(.slow_incdec)) {
174199 try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1));
174200 } else {
174201 try self.asmRegister(.{ ._c, .in }, index_reg.to32());
174202 }
174203 try self.asmRegisterImmediate(.{ ._, .cmp }, index_reg.to32(), .u(limbs_len));
174204 const zero = try self.asmJccReloc(.nb, undefined);
174205 try self.asmMemoryImmediate(.{ ._, .cmp }, .{
174206 .base = .{ .frame = src_frame_addr.index },
174207 .mod = .{ .rm = .{
174208 .size = .qword,
174209 .index = index_reg.to64(),
174210 .scale = .@"8",
174211 .disp = src_frame_addr.off,
174212 } },
174213 }, .u(0));
174214 _ = try self.asmJccReloc(.e, loop);
174215 try self.asmRegisterMemory(.{ ._f, .bs }, dst_reg.to64(), .{
174216 .base = .{ .frame = src_frame_addr.index },
174217 .mod = .{ .rm = .{
174218 .size = .qword,
174219 .index = index_reg.to64(),
174220 .scale = .@"8",
174221 .disp = src_frame_addr.off,
174222 } },
174223 });
174224 self.performReloc(zero);
174225 try self.asmRegisterImmediate(.{ ._l, .sh }, index_reg.to32(), .u(6));
174226 try self.asmRegisterRegister(.{ ._, .add }, dst_reg.to32(), index_reg.to32());
174227 break :result dst_mcv;
174228 }
174229
174230 const wide_ty: Type = if (src_bits <= 8) .u16 else src_ty;
174231 if (has_bmi) {
174232 if (src_bits <= 64) {
174233 const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0);
174234 const masked_mcv = if (extra_bits > 0) masked: {
174235 const tmp_mcv = tmp: {
174236 if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0))
174237 break :tmp src_mcv;
174238 try self.genSetReg(dst_reg, wide_ty, src_mcv, .{});
174239 break :tmp dst_mcv;
174240 };
174241 try self.genBinOpMir(
174242 .{ ._, .@"or" },
174243 wide_ty,
174244 tmp_mcv,
174245 .{ .immediate = (@as(u64, std.math.maxInt(u64)) >> @intCast(64 - extra_bits)) <<
174246 @intCast(src_bits) },
174247 );
174248 break :masked tmp_mcv;
174249 } else mat_src_mcv;
174250 try self.genBinOpMir(.{ ._, .tzcnt }, wide_ty, dst_mcv, masked_mcv);
174251 } else {
174252 assert(src_bits <= 128);
174253 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
174254 const tmp_mcv = MCValue{ .register = tmp_reg };
174255 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
174256 defer self.register_manager.unlockReg(tmp_lock);
174257
174258 const lo_mat_src_mcv: MCValue = if (mat_src_mcv.isBase())
174259 mat_src_mcv
174260 else
174261 .{ .register = mat_src_mcv.register_pair[0] };
174262 const hi_mat_src_mcv: MCValue = if (mat_src_mcv.isBase())
174263 mat_src_mcv.address().offset(8).deref()
174264 else
174265 .{ .register = mat_src_mcv.register_pair[1] };
174266 const masked_mcv = if (src_bits < 128) masked: {
174267 try self.genCopy(.u64, dst_mcv, hi_mat_src_mcv, .{});
174268 try self.genBinOpMir(
174269 .{ ._, .@"or" },
174270 .u64,
174271 dst_mcv,
174272 .{ .immediate = @as(u64, std.math.maxInt(u64)) << @intCast(src_bits - 64) },
174273 );
174274 break :masked dst_mcv;
174275 } else hi_mat_src_mcv;
174276 try self.genBinOpMir(.{ ._, .tzcnt }, .u64, dst_mcv, masked_mcv);
174277 try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 });
174278 try self.genBinOpMir(.{ ._, .tzcnt }, .u64, tmp_mcv, lo_mat_src_mcv);
174279 try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32());
174280 }
174281 break :result dst_mcv;
174282 }
174283
174284 assert(src_bits <= 64);
174285 const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits });
174286 const width_lock = self.register_manager.lockRegAssumeUnused(width_reg);
174287 defer self.register_manager.unlockReg(width_lock);
174288
174289 if (src_bits <= 8 or !std.math.isPowerOfTwo(src_bits)) {
174290 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
174291 const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg);
174292 defer self.register_manager.unlockReg(wide_lock);
174293
174294 try self.truncateRegister(src_ty, wide_reg);
174295 try self.genBinOpMir(.{ ._f, .bs }, wide_ty, dst_mcv, .{ .register = wide_reg });
174296 } else try self.genBinOpMir(.{ ._f, .bs }, src_ty, dst_mcv, mat_src_mcv);
174297
174298 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(zcu))), 2);
174299 try self.asmCmovccRegisterRegister(
174300 .z,
174301 registerAlias(dst_reg, cmov_abi_size),
174302 registerAlias(width_reg, cmov_abi_size),
174303 );
174304 break :result dst_mcv;
174305 };
174306 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
174307}
174308
174309fn airPopCount(self: *CodeGen, inst: Air.Inst.Index) !void {
174310 const pt = self.pt;
174311 const zcu = pt.zcu;
174312 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
174313 const result: MCValue = result: {
174314 try self.spillEflagsIfOccupied();
174315
174316 const src_ty = self.typeOf(ty_op.operand);
174317 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
174318 if (src_ty.zigTypeTag(zcu) == .vector or src_abi_size > 16)
174319 return self.fail("TODO implement airPopCount for {f}", .{src_ty.fmt(pt)});
174320 const src_mcv = try self.resolveInst(ty_op.operand);
174321
174322 const mat_src_mcv = switch (src_mcv) {
174323 .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) },
174324 else => src_mcv,
174325 };
174326 const mat_src_lock = switch (mat_src_mcv) {
174327 .register => |reg| self.register_manager.lockReg(reg),
174328 else => null,
174329 };
174330 defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock);
174331
174332 if (src_abi_size <= 8) {
174333 const dst_contains_src =
174334 src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv);
174335 const dst_reg = if (dst_contains_src)
174336 src_mcv.getReg().?
174337 else
174338 try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
174339 const dst_lock = self.register_manager.lockReg(dst_reg);
174340 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
174341
174342 try self.genPopCount(dst_reg, src_ty, mat_src_mcv, dst_contains_src);
174343 break :result .{ .register = dst_reg };
174344 }
174345
174346 assert(src_abi_size > 8 and src_abi_size <= 16);
174347 const tmp_regs = try self.register_manager.allocRegs(2, .{ inst, null }, abi.RegisterClass.gp);
174348 const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs);
174349 defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock);
174350
174351 try self.genPopCount(tmp_regs[0], .usize, if (mat_src_mcv.isBase())
174352 mat_src_mcv
174353 else
174354 .{ .register = mat_src_mcv.register_pair[0] }, false);
174355 const src_info = src_ty.intInfo(zcu);
174356 const hi_ty = try pt.intType(src_info.signedness, (src_info.bits - 1) % 64 + 1);
174357 try self.genPopCount(tmp_regs[1], hi_ty, if (mat_src_mcv.isBase())
174358 mat_src_mcv.address().offset(8).deref()
174359 else
174360 .{ .register = mat_src_mcv.register_pair[1] }, false);
174361 try self.asmRegisterRegister(.{ ._, .add }, tmp_regs[0].to8(), tmp_regs[1].to8());
174362 break :result .{ .register = tmp_regs[0] };
174363 };
174364 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
174365}
174366
174367fn genPopCount(
174368 self: *CodeGen,
174369 dst_reg: Register,
174370 src_ty: Type,
174371 src_mcv: MCValue,
174372 dst_contains_src: bool,
174373) !void {
174374 const pt = self.pt;
174375
174376 const src_abi_size: u32 = @intCast(src_ty.abiSize(pt.zcu));
174377 if (self.hasFeature(.popcnt)) return self.genBinOpMir(
174378 .{ ._, .popcnt },
174379 if (src_abi_size > 1) src_ty else .u32,
174380 .{ .register = dst_reg },
174381 if (src_abi_size > 1) src_mcv else src: {
174382 if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{});
174383 try self.truncateRegister(try src_ty.toUnsigned(pt), dst_reg);
174384 break :src .{ .register = dst_reg };
174385 },
174386 );
174387
174388 const mask = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - src_abi_size * 8);
174389 const imm_0_1: Immediate = .u(mask / 0b1_1);
174390 const imm_00_11: Immediate = .u(mask / 0b01_01);
174391 const imm_0000_1111: Immediate = .u(mask / 0b0001_0001);
174392 const imm_0000_0001: Immediate = .u(mask / 0b1111_1111);
174393
174394 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
174395 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
174396 defer self.register_manager.unlockReg(tmp_lock);
174397
174398 const dst = registerAlias(dst_reg, src_abi_size);
174399 const tmp = registerAlias(tmp_reg, src_abi_size);
174400 const imm = if (src_abi_size > 4)
174401 try self.register_manager.allocReg(null, abi.RegisterClass.gp)
174402 else
174403 undefined;
174404
174405 if (!dst_contains_src) try self.genSetReg(dst, src_ty, src_mcv, .{});
174406 // dst = operand
174407 try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst);
174408 // tmp = operand
174409 try self.asmRegisterImmediate(.{ ._r, .sh }, tmp, .u(1));
174410 // tmp = operand >> 1
174411 if (src_abi_size > 4) {
174412 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_0_1);
174413 try self.asmRegisterRegister(.{ ._, .@"and" }, tmp, imm);
174414 } else try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_0_1);
174415 // tmp = (operand >> 1) & 0x55...55
174416 try self.asmRegisterRegister(.{ ._, .sub }, dst, tmp);
174417 // dst = temp1 = operand - ((operand >> 1) & 0x55...55)
174418 try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst);
174419 // tmp = temp1
174420 try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u(2));
174421 // dst = temp1 >> 2
174422 if (src_abi_size > 4) {
174423 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_00_11);
174424 try self.asmRegisterRegister(.{ ._, .@"and" }, tmp, imm);
174425 try self.asmRegisterRegister(.{ ._, .@"and" }, dst, imm);
174426 } else {
174427 try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_00_11);
174428 try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_00_11);
174429 }
174430 // tmp = temp1 & 0x33...33
174431 // dst = (temp1 >> 2) & 0x33...33
174432 try self.asmRegisterRegister(.{ ._, .add }, tmp, dst);
174433 // tmp = temp2 = (temp1 & 0x33...33) + ((temp1 >> 2) & 0x33...33)
174434 try self.asmRegisterRegister(.{ ._, .mov }, dst, tmp);
174435 // dst = temp2
174436 try self.asmRegisterImmediate(.{ ._r, .sh }, tmp, .u(4));
174437 // tmp = temp2 >> 4
174438 try self.asmRegisterRegister(.{ ._, .add }, dst, tmp);
174439 // dst = temp2 + (temp2 >> 4)
174440 if (src_abi_size > 4) {
174441 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_0000_1111);
174442 try self.asmRegisterImmediate(.{ ._, .mov }, tmp, imm_0000_0001);
174443 try self.asmRegisterRegister(.{ ._, .@"and" }, dst, imm);
174444 try self.asmRegisterRegister(.{ .i_, .mul }, dst, tmp);
174445 } else {
174446 try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_0000_1111);
174447 if (src_abi_size > 1) {
174448 try self.asmRegisterRegisterImmediate(.{ .i_, .mul }, dst, dst, imm_0000_0001);
174449 }
174450 }
174451 // dst = temp3 = (temp2 + (temp2 >> 4)) & 0x0f...0f
174452 // dst = temp3 * 0x01...01
174453 if (src_abi_size > 1) {
174454 try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u((src_abi_size - 1) * 8));
174455 }
174456 // dst = (temp3 * 0x01...01) >> (bits - 8)
174457}
174458
174459fn genByteSwap(
174304fn genUnwrapErrUnionPayloadMir(
174460174305 self: *CodeGen,
174461 inst: Air.Inst.Index,
174462 src_ty: Type,
174463 src_mcv: MCValue,
174464 mem_ok: bool,
174306 maybe_inst: ?Air.Inst.Index,
174307 err_union_ty: Type,
174308 err_union: MCValue,
174465174309) !MCValue {
174466174310 const pt = self.pt;
174467174311 const zcu = pt.zcu;
174468 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
174469 const has_movbe = self.hasFeature(.movbe);
174470
174471 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail(
174472 "TODO implement genByteSwap for {f}",
174473 .{src_ty.fmt(pt)},
174474 );
174475
174476 const src_lock = switch (src_mcv) {
174477 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
174478 else => null,
174479 };
174480 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
174481
174482 const abi_size: u32 = @intCast(src_ty.abiSize(zcu));
174483 switch (abi_size) {
174484 0 => unreachable,
174485 1 => return if ((mem_ok or src_mcv.isRegister()) and
174486 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
174487 src_mcv
174488 else
174489 try self.copyToRegisterWithInstTracking(inst, src_ty, src_mcv),
174490 2 => if ((mem_ok or src_mcv.isRegister()) and
174491 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
174492 {
174493 try self.genBinOpMir(.{ ._l, .ro }, src_ty, src_mcv, .{ .immediate = 8 });
174494 return src_mcv;
174495 },
174496 3...8 => if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) {
174497 try self.genUnOpMir(.{ .b_, .swap }, src_ty, src_mcv);
174498 return src_mcv;
174499 },
174500 9...16 => {
174501 const mat_src_mcv: MCValue = mat_src_mcv: switch (src_mcv) {
174502 .register => {
174503 const frame_index = try self.allocFrameIndex(.initSpill(src_ty, zcu));
174504 try self.genSetMem(.{ .frame = frame_index }, 0, src_ty, src_mcv, .{});
174505 break :mat_src_mcv .{ .load_frame = .{ .index = frame_index } };
174506 },
174507 .register_pair => |src_regs| if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) {
174508 for (src_regs) |src_reg| try self.asmRegister(.{ .b_, .swap }, src_reg.to64());
174509 return .{ .register_pair = .{ src_regs[1], src_regs[0] } };
174510 } else src_mcv,
174511 else => src_mcv,
174512 };
174513
174514 const dst_regs =
174515 try self.register_manager.allocRegs(2, .{ inst, inst }, abi.RegisterClass.gp);
174516 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
174517 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
174518
174519 for (dst_regs, 0..) |dst_reg, limb_index| {
174520 if (mat_src_mcv.isBase()) {
174521 try self.asmRegisterMemory(
174522 .{ if (has_movbe) ._be else ._, .mov },
174523 dst_reg.to64(),
174524 try mat_src_mcv.address().offset(@intCast(limb_index * 8)).deref().mem(self, .{ .size = .qword }),
174525 );
174526 if (!has_movbe) try self.asmRegister(.{ .b_, .swap }, dst_reg.to64());
174527 } else {
174528 try self.asmRegisterRegister(
174529 .{ ._, .mov },
174530 dst_reg.to64(),
174531 mat_src_mcv.register_pair[limb_index].to64(),
174532 );
174533 try self.asmRegister(.{ .b_, .swap }, dst_reg.to64());
174534 }
174535 }
174536 return .{ .register_pair = .{ dst_regs[1], dst_regs[0] } };
174537 },
174538 else => {
174539 const limbs_len = std.math.divCeil(u32, abi_size, 8) catch unreachable;
174540
174541 const temp_regs =
174542 try self.register_manager.allocRegs(4, @splat(null), abi.RegisterClass.gp);
174543 const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs);
174544 defer for (temp_locks) |lock| self.register_manager.unlockReg(lock);
174545
174546 const dst_mcv = try self.allocRegOrMem(inst, false);
174547 try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[0].to32(), temp_regs[0].to32());
174548 try self.asmRegisterImmediate(.{ ._, .mov }, temp_regs[1].to32(), .u(limbs_len - 1));
174549
174550 const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
174551 try self.asmRegisterMemory(
174552 .{ if (has_movbe) ._be else ._, .mov },
174553 temp_regs[2].to64(),
174554 .{
174555 .base = .{ .frame = dst_mcv.load_frame.index },
174556 .mod = .{ .rm = .{
174557 .size = .qword,
174558 .index = temp_regs[0].to64(),
174559 .scale = .@"8",
174560 .disp = dst_mcv.load_frame.off,
174561 } },
174562 },
174563 );
174564 try self.asmRegisterMemory(
174565 .{ if (has_movbe) ._be else ._, .mov },
174566 temp_regs[3].to64(),
174567 .{
174568 .base = .{ .frame = dst_mcv.load_frame.index },
174569 .mod = .{ .rm = .{
174570 .size = .qword,
174571 .index = temp_regs[1].to64(),
174572 .scale = .@"8",
174573 .disp = dst_mcv.load_frame.off,
174574 } },
174575 },
174576 );
174577 if (!has_movbe) {
174578 try self.asmRegister(.{ .b_, .swap }, temp_regs[2].to64());
174579 try self.asmRegister(.{ .b_, .swap }, temp_regs[3].to64());
174580 }
174581 try self.asmMemoryRegister(.{ ._, .mov }, .{
174582 .base = .{ .frame = dst_mcv.load_frame.index },
174583 .mod = .{ .rm = .{
174584 .size = .qword,
174585 .index = temp_regs[0].to64(),
174586 .scale = .@"8",
174587 .disp = dst_mcv.load_frame.off,
174588 } },
174589 }, temp_regs[3].to64());
174590 try self.asmMemoryRegister(.{ ._, .mov }, .{
174591 .base = .{ .frame = dst_mcv.load_frame.index },
174592 .mod = .{ .rm = .{
174593 .size = .qword,
174594 .index = temp_regs[1].to64(),
174595 .scale = .@"8",
174596 .disp = dst_mcv.load_frame.off,
174597 } },
174598 }, temp_regs[2].to64());
174599 if (self.hasFeature(.slow_incdec)) {
174600 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
174601 try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1));
174602 } else {
174603 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
174604 try self.asmRegister(.{ ._c, .de }, temp_regs[1].to32());
174605 }
174606 try self.asmRegisterRegister(.{ ._, .cmp }, temp_regs[0].to32(), temp_regs[1].to32());
174607 _ = try self.asmJccReloc(.be, loop);
174608 return dst_mcv;
174609 },
174610 }
174611
174612 const dst_mcv: MCValue = if (mem_ok and has_movbe and src_mcv.isRegister())
174613 try self.allocRegOrMem(inst, true)
174614 else
174615 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.gp) };
174616 if (dst_mcv.getReg()) |dst_reg| {
174617 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register);
174618 defer self.register_manager.unlockReg(dst_lock);
174619
174620 try self.genSetReg(dst_reg, src_ty, src_mcv, .{});
174621 switch (abi_size) {
174622 else => unreachable,
174623 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }),
174624 3...8 => try self.genUnOpMir(.{ .b_, .swap }, src_ty, dst_mcv),
174625 }
174626 } else try self.genBinOpMir(.{ ._be, .mov }, src_ty, dst_mcv, src_mcv);
174627 return dst_mcv;
174628}
174629
174630fn airByteSwap(self: *CodeGen, inst: Air.Inst.Index) !void {
174631 const pt = self.pt;
174632 const zcu = pt.zcu;
174633 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
174634
174635 const src_ty = self.typeOf(ty_op.operand);
174636 const src_bits: u32 = @intCast(src_ty.bitSize(zcu));
174637 const src_mcv = try self.resolveInst(ty_op.operand);
174638
174639 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true);
174640 try self.genShiftBinOpMir(
174641 .{ ._r, switch (if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned) {
174642 .signed => .sa,
174643 .unsigned => .sh,
174644 } },
174645 src_ty,
174646 dst_mcv,
174647 if (src_bits > 256) .u16 else .u8,
174648 .{ .immediate = src_ty.abiSize(zcu) * 8 - src_bits },
174649 );
174650 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
174651}
174652
174653fn airBitReverse(self: *CodeGen, inst: Air.Inst.Index) !void {
174654 const pt = self.pt;
174655 const zcu = pt.zcu;
174656 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
174657
174658 const src_ty = self.typeOf(ty_op.operand);
174659 const abi_size: u32 = @intCast(src_ty.abiSize(zcu));
174660 const bit_size: u32 = @intCast(src_ty.bitSize(zcu));
174661 const src_mcv = try self.resolveInst(ty_op.operand);
174662
174663 const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, false);
174664 const dst_locks: [2]?RegisterLock = switch (dst_mcv) {
174665 .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null },
174666 .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs),
174667 else => unreachable,
174668 };
174669 defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock);
174670
174671 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
174672 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
174673 defer self.register_manager.unlockReg(tmp_lock);
174674
174675 const limb_abi_size: u32 = @min(abi_size, 8);
174676 const tmp = registerAlias(tmp_reg, limb_abi_size);
174677 const imm = if (limb_abi_size > 4)
174678 try self.register_manager.allocReg(null, abi.RegisterClass.gp)
174679 else
174680 undefined;
174681
174682 const mask = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - limb_abi_size * 8);
174683 const imm_0000_1111: Immediate = .u(mask / 0b0001_0001);
174684 const imm_00_11: Immediate = .u(mask / 0b01_01);
174685 const imm_0_1: Immediate = .u(mask / 0b1_1);
174686
174687 for (dst_mcv.getRegs()) |dst_reg| {
174688 const dst = registerAlias(dst_reg, limb_abi_size);
174689
174690 // dst = temp1 = bswap(operand)
174691 try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst);
174692 // tmp = temp1
174693 try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u(4));
174694 // dst = temp1 >> 4
174695 if (limb_abi_size > 4) {
174696 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_0000_1111);
174697 try self.asmRegisterRegister(.{ ._, .@"and" }, tmp, imm);
174698 try self.asmRegisterRegister(.{ ._, .@"and" }, dst, imm);
174699 } else {
174700 try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_0000_1111);
174701 try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_0000_1111);
174702 }
174703 // tmp = temp1 & 0x0f...0f
174704 // dst = (temp1 >> 4) & 0x0f...0f
174705 try self.asmRegisterImmediate(.{ ._l, .sh }, tmp, .u(4));
174706 // tmp = (temp1 & 0x0f...0f) << 4
174707 try self.asmRegisterRegister(.{ ._, .@"or" }, dst, tmp);
174708 // dst = temp2 = ((temp1 >> 4) & 0x0f...0f) | ((temp1 & 0x0f...0f) << 4)
174709 try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst);
174710 // tmp = temp2
174711 try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u(2));
174712 // dst = temp2 >> 2
174713 if (limb_abi_size > 4) {
174714 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_00_11);
174715 try self.asmRegisterRegister(.{ ._, .@"and" }, tmp, imm);
174716 try self.asmRegisterRegister(.{ ._, .@"and" }, dst, imm);
174717 } else {
174718 try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_00_11);
174719 try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_00_11);
174720 }
174721 // tmp = temp2 & 0x33...33
174722 // dst = (temp2 >> 2) & 0x33...33
174723 try self.asmRegisterMemory(
174724 .{ ._, .lea },
174725 if (limb_abi_size > 4) tmp.to64() else tmp.to32(),
174726 .{
174727 .base = .{ .reg = dst.to64() },
174728 .mod = .{ .rm = .{
174729 .index = tmp.to64(),
174730 .scale = .@"4",
174731 } },
174732 },
174733 );
174734 // tmp = temp3 = ((temp2 >> 2) & 0x33...33) + ((temp2 & 0x33...33) << 2)
174735 try self.asmRegisterRegister(.{ ._, .mov }, dst, tmp);
174736 // dst = temp3
174737 try self.asmRegisterImmediate(.{ ._r, .sh }, tmp, .u(1));
174738 // tmp = temp3 >> 1
174739 if (limb_abi_size > 4) {
174740 try self.asmRegisterImmediate(.{ ._, .mov }, imm, imm_0_1);
174741 try self.asmRegisterRegister(.{ ._, .@"and" }, dst, imm);
174742 try self.asmRegisterRegister(.{ ._, .@"and" }, tmp, imm);
174743 } else {
174744 try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_0_1);
174745 try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_0_1);
174746 }
174747 // dst = temp3 & 0x55...55
174748 // tmp = (temp3 >> 1) & 0x55...55
174749 try self.asmRegisterMemory(
174750 .{ ._, .lea },
174751 if (limb_abi_size > 4) dst.to64() else dst.to32(),
174752 .{
174753 .base = .{ .reg = tmp.to64() },
174754 .mod = .{ .rm = .{
174755 .index = dst.to64(),
174756 .scale = .@"2",
174757 } },
174758 },
174759 );
174760 // dst = ((temp3 >> 1) & 0x55...55) + ((temp3 & 0x55...55) << 1)
174761 }
174762
174763 const extra_bits = abi_size * 8 - bit_size;
174764 const signedness: std.builtin.Signedness =
174765 if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned;
174766 if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) {
174767 .signed => .{ ._r, .sa },
174768 .unsigned => .{ ._r, .sh },
174769 }, src_ty, dst_mcv, .u8, .{ .immediate = extra_bits });
174770
174771 return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
174772}
174773
174774fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: Air.Inst.Ref, ty: Type) !void {
174775 const pt = self.pt;
174776 const zcu = pt.zcu;
174777
174778 const result = result: {
174779 const scalar_bits = ty.scalarType(zcu).floatBits(self.target);
174780 if (scalar_bits == 80) {
174781 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement floatSign for {f}", .{
174782 ty.fmt(pt),
174783 });
174784
174785 const src_mcv = try self.resolveInst(operand);
174786 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
174787 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
174788
174789 const dst_mcv: MCValue = .{ .register = .st0 };
174790 if (!std.meta.eql(src_mcv, dst_mcv) or !self.reuseOperand(inst, operand, 0, src_mcv))
174791 try self.register_manager.getKnownReg(.st0, inst);
174792
174793 try self.genCopy(ty, dst_mcv, src_mcv, .{});
174794 switch (tag) {
174795 .neg => try self.asmOpOnly(.{ .f_, .chs }),
174796 .abs => try self.asmOpOnly(.{ .f_, .abs }),
174797 else => unreachable,
174798 }
174799 break :result dst_mcv;
174800 }
174801
174802 const abi_size: u32 = switch (ty.abiSize(zcu)) {
174803 1...16 => 16,
174804 17...32 => 32,
174805 else => return self.fail("TODO implement floatSign for {f}", .{
174806 ty.fmt(pt),
174807 }),
174808 };
174809
174810 const src_mcv = try self.resolveInst(operand);
174811 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
174812 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
174813
174814 const dst_mcv: MCValue = if (src_mcv.isRegister() and
174815 self.reuseOperand(inst, operand, 0, src_mcv))
174816 src_mcv
174817 else if (self.hasFeature(.avx))
174818 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.sse) }
174819 else
174820 try self.copyToRegisterWithInstTracking(inst, ty, src_mcv);
174821 const dst_reg = dst_mcv.getReg().?;
174822 const dst_lock = self.register_manager.lockReg(dst_reg);
174823 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
174312 const payload_ty = err_union_ty.errorUnionPayload(zcu);
174824174313
174825 const vec_ty = try pt.vectorType(.{
174826 .len = @divExact(abi_size * 8, scalar_bits),
174827 .child = (try pt.intType(.signed, scalar_bits)).ip_index,
174828 });
174314 const result: MCValue = result: {
174315 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
174829174316
174830 const sign_mcv = try self.lowerValue(switch (tag) {
174831 .neg => try vec_ty.minInt(pt, vec_ty),
174832 .abs => try vec_ty.maxInt(pt, vec_ty),
174833 else => unreachable,
174834 });
174835 const sign_mem: Memory = if (sign_mcv.isBase())
174836 try sign_mcv.mem(self, .{ .size = .fromSize(abi_size) })
174837 else
174838 .{
174839 .base = .{ .reg = try self.copyToTmpRegister(.usize, sign_mcv.address()) },
174840 .mod = .{ .rm = .{ .size = .fromSize(abi_size) } },
174841 };
174317 const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
174318 switch (err_union) {
174319 .load_frame => |frame_addr| break :result .{ .load_frame = .{
174320 .index = frame_addr.index,
174321 .off = frame_addr.off + payload_off,
174322 } },
174323 .register => |reg| {
174324 // TODO reuse operand
174325 const eu_lock = self.register_manager.lockReg(reg);
174326 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
174842174327
174843 if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory(
174844 switch (scalar_bits) {
174845 16, 128 => if (abi_size <= 16 or self.hasFeature(.avx2)) switch (tag) {
174846 .neg => .{ .vp_, .xor },
174847 .abs => .{ .vp_, .@"and" },
174848 else => unreachable,
174849 } else switch (tag) {
174850 .neg => .{ .v_ps, .xor },
174851 .abs => .{ .v_ps, .@"and" },
174852 else => unreachable,
174853 },
174854 32 => switch (tag) {
174855 .neg => .{ .v_ps, .xor },
174856 .abs => .{ .v_ps, .@"and" },
174857 else => unreachable,
174858 },
174859 64 => switch (tag) {
174860 .neg => .{ .v_pd, .xor },
174861 .abs => .{ .v_pd, .@"and" },
174862 else => unreachable,
174863 },
174864 80 => return self.fail("TODO implement floatSign for {f}", .{ty.fmt(pt)}),
174865 else => unreachable,
174866 },
174867 registerAlias(dst_reg, abi_size),
174868 registerAlias(if (src_mcv.isRegister())
174869 src_mcv.getReg().?
174870 else
174871 try self.copyToTmpRegister(ty, src_mcv), abi_size),
174872 sign_mem,
174873 ) else try self.asmRegisterMemory(
174874 switch (scalar_bits) {
174875 16, 128 => switch (tag) {
174876 .neg => .{ .p_, .xor },
174877 .abs => .{ .p_, .@"and" },
174878 else => unreachable,
174879 },
174880 32 => switch (tag) {
174881 .neg => .{ ._ps, .xor },
174882 .abs => .{ ._ps, .@"and" },
174883 else => unreachable,
174884 },
174885 64 => switch (tag) {
174886 .neg => .{ ._pd, .xor },
174887 .abs => .{ ._pd, .@"and" },
174888 else => unreachable,
174889 },
174890 80 => return self.fail("TODO implement floatSign for {f}", .{ty.fmt(pt)}),
174891 else => unreachable,
174328 const payload_in_gp = self.regSetForType(payload_ty).supersetOf(abi.RegisterClass.gp);
174329 const result_mcv: MCValue = if (payload_in_gp and maybe_inst != null)
174330 try self.copyToRegisterWithInstTracking(maybe_inst.?, err_union_ty, err_union)
174331 else
174332 .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };
174333 if (payload_off > 0) try self.genShiftBinOpMir(
174334 .{ ._r, .sh },
174335 err_union_ty,
174336 result_mcv,
174337 .u8,
174338 .{ .immediate = @as(u6, @intCast(payload_off * 8)) },
174339 ) else try self.truncateRegister(payload_ty, result_mcv.register);
174340 break :result if (payload_in_gp)
174341 result_mcv
174342 else if (maybe_inst) |inst|
174343 try self.copyToRegisterWithInstTracking(inst, payload_ty, result_mcv)
174344 else
174345 .{ .register = try self.copyToTmpRegister(payload_ty, result_mcv) };
174892174346 },
174893 registerAlias(dst_reg, abi_size),
174894 sign_mem,
174895 );
174896 break :result dst_mcv;
174897 };
174898 return self.finishAir(inst, result, .{ operand, .none, .none });
174899}
174900
174901fn airFloatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
174902 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
174903 const ty = self.typeOf(un_op);
174904 return self.floatSign(inst, tag, un_op, ty);
174905}
174906
174907fn airRound(self: *CodeGen, inst: Air.Inst.Index, mode: bits.RoundMode) !void {
174908 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
174909 const ty = self.typeOf(un_op);
174910
174911 const result = result: {
174912 switch (try self.genRoundLibcall(ty, .{ .air_ref = un_op }, mode)) {
174913 .none => {},
174914 else => |dst_mcv| break :result dst_mcv,
174347 else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {f}", .{err_union}),
174915174348 }
174916
174917 const src_mcv = try self.resolveInst(un_op);
174918 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
174919 src_mcv
174920 else
174921 try self.copyToRegisterWithInstTracking(inst, ty, src_mcv);
174922 const dst_reg = dst_mcv.getReg().?;
174923 const dst_lock = self.register_manager.lockReg(dst_reg);
174924 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
174925 try self.genRound(ty, dst_reg, src_mcv, mode);
174926 break :result dst_mcv;
174927 };
174928 return self.finishAir(inst, result, .{ un_op, .none, .none });
174929}
174930
174931fn getRoundTag(self: *CodeGen, ty: Type) ?Mir.Inst.FixedTag {
174932 const pt = self.pt;
174933 const zcu = pt.zcu;
174934 return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(zcu)) {
174935 .float => switch (ty.floatBits(self.target)) {
174936 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
174937 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },
174938 16, 80, 128 => null,
174939 else => unreachable,
174940 },
174941 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
174942 .float => switch (ty.childType(zcu).floatBits(self.target)) {
174943 32 => switch (ty.vectorLen(zcu)) {
174944 1 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
174945 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else .{ ._ps, .round },
174946 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else null,
174947 else => null,
174948 },
174949 64 => switch (ty.vectorLen(zcu)) {
174950 1 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },
174951 2 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else .{ ._pd, .round },
174952 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else null,
174953 else => null,
174954 },
174955 16, 80, 128 => null,
174956 else => unreachable,
174957 },
174958 else => null,
174959 },
174960 else => unreachable,
174961 } else null;
174962}
174963
174964fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: bits.RoundMode) !MCValue {
174965 const pt = self.pt;
174966 const zcu = pt.zcu;
174967 if (self.getRoundTag(ty)) |_| return .none;
174968
174969 if (ty.zigTypeTag(zcu) != .float)
174970 return self.fail("TODO implement genRound for {f}", .{ty.fmt(pt)});
174971
174972 var sym_buf: ["__trunc?".len]u8 = undefined;
174973 return try self.genCall(.{ .extern_func = .{
174974 .return_type = ty.toIntern(),
174975 .param_types = &.{ty.toIntern()},
174976 .sym = std.fmt.bufPrint(&sym_buf, "{s}{s}{s}", .{
174977 floatLibcAbiPrefix(ty),
174978 switch (mode.direction) {
174979 .down => "floor",
174980 .up => "ceil",
174981 .zero => "trunc",
174982 else => unreachable,
174983 },
174984 floatLibcAbiSuffix(ty),
174985 }) catch unreachable,
174986 } }, &.{ty}, &.{src_mcv}, .{});
174987}
174988
174989fn genRound(self: *CodeGen, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: bits.RoundMode) !void {
174990 const pt = self.pt;
174991 const mir_tag = self.getRoundTag(ty) orelse {
174992 const result = try self.genRoundLibcall(ty, src_mcv, mode);
174993 return self.genSetReg(dst_reg, ty, result, .{});
174994174349 };
174995 const abi_size: u32 = @intCast(ty.abiSize(pt.zcu));
174996 const dst_alias = registerAlias(dst_reg, abi_size);
174997 switch (mir_tag[0]) {
174998 .v_ss, .v_sd => if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
174999 mir_tag,
175000 dst_alias,
175001 dst_alias,
175002 try src_mcv.mem(self, .{ .size = .fromSize(abi_size) }),
175003 mode.imm(),
175004 ) else try self.asmRegisterRegisterRegisterImmediate(
175005 mir_tag,
175006 dst_alias,
175007 dst_alias,
175008 registerAlias(if (src_mcv.isRegister())
175009 src_mcv.getReg().?
175010 else
175011 try self.copyToTmpRegister(ty, src_mcv), abi_size),
175012 mode.imm(),
175013 ),
175014 else => if (src_mcv.isBase()) try self.asmRegisterMemoryImmediate(
175015 mir_tag,
175016 dst_alias,
175017 try src_mcv.mem(self, .{ .size = .fromSize(abi_size) }),
175018 mode.imm(),
175019 ) else try self.asmRegisterRegisterImmediate(
175020 mir_tag,
175021 dst_alias,
175022 registerAlias(if (src_mcv.isRegister())
175023 src_mcv.getReg().?
175024 else
175025 try self.copyToTmpRegister(ty, src_mcv), abi_size),
175026 mode.imm(),
175027 ),
175028 }
175029}
175030
175031fn airAbs(self: *CodeGen, inst: Air.Inst.Index) !void {
175032 const pt = self.pt;
175033 const zcu = pt.zcu;
175034 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
175035 const ty = self.typeOf(ty_op.operand);
175036
175037 const result: MCValue = result: {
175038 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(zcu)) {
175039 else => null,
175040 .int => switch (ty.abiSize(zcu)) {
175041 0 => unreachable,
175042 1...8 => {
175043 try self.spillEflagsIfOccupied();
175044 const src_mcv = try self.resolveInst(ty_op.operand);
175045 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, src_mcv);
175046
175047 try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv);
175048
175049 const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(zcu))), 2);
175050 switch (src_mcv) {
175051 .register => |val_reg| try self.asmCmovccRegisterRegister(
175052 .l,
175053 registerAlias(dst_mcv.register, cmov_abi_size),
175054 registerAlias(val_reg, cmov_abi_size),
175055 ),
175056 .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory(
175057 .l,
175058 registerAlias(dst_mcv.register, cmov_abi_size),
175059 try src_mcv.mem(self, .{ .size = .fromSize(cmov_abi_size) }),
175060 ),
175061 else => {
175062 const val_reg = try self.copyToTmpRegister(ty, src_mcv);
175063 try self.asmCmovccRegisterRegister(
175064 .l,
175065 registerAlias(dst_mcv.register, cmov_abi_size),
175066 registerAlias(val_reg, cmov_abi_size),
175067 );
175068 },
175069 }
175070 break :result dst_mcv;
175071 },
175072 9...16 => {
175073 try self.spillEflagsIfOccupied();
175074 const src_mcv = try self.resolveInst(ty_op.operand);
175075 const dst_mcv = if (src_mcv == .register_pair and
175076 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
175077 const dst_regs = try self.register_manager.allocRegs(
175078 2,
175079 .{ inst, inst },
175080 abi.RegisterClass.gp,
175081 );
175082 const dst_mcv: MCValue = .{ .register_pair = dst_regs };
175083 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
175084 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
175085
175086 try self.genCopy(ty, dst_mcv, src_mcv, .{});
175087 break :dst dst_mcv;
175088 };
175089 const dst_regs = dst_mcv.register_pair;
175090 const dst_locks = self.register_manager.lockRegs(2, dst_regs);
175091 defer for (dst_locks) |dst_lock| if (dst_lock) |lock|
175092 self.register_manager.unlockReg(lock);
175093
175094 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
175095 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
175096 defer self.register_manager.unlockReg(tmp_lock);
175097
175098 try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_regs[1]);
175099 try self.asmRegisterImmediate(.{ ._r, .sa }, tmp_reg, .u(63));
175100 try self.asmRegisterRegister(.{ ._, .xor }, dst_regs[0], tmp_reg);
175101 try self.asmRegisterRegister(.{ ._, .xor }, dst_regs[1], tmp_reg);
175102 try self.asmRegisterRegister(.{ ._, .sub }, dst_regs[0], tmp_reg);
175103 try self.asmRegisterRegister(.{ ._, .sbb }, dst_regs[1], tmp_reg);
175104
175105 break :result dst_mcv;
175106 },
175107 else => {
175108 const abi_size: u31 = @intCast(ty.abiSize(zcu));
175109 const limb_len = std.math.divCeil(u31, abi_size, 8) catch unreachable;
175110
175111 const tmp_regs =
175112 try self.register_manager.allocRegs(3, @splat(null), abi.RegisterClass.gp);
175113 const tmp_locks = self.register_manager.lockRegsAssumeUnused(3, tmp_regs);
175114 defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock);
175115
175116 try self.spillEflagsIfOccupied();
175117 const src_mcv = try self.resolveInst(ty_op.operand);
175118 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
175119 src_mcv
175120 else
175121 try self.allocRegOrMem(inst, false);
175122
175123 try self.asmMemoryImmediate(
175124 .{ ._, .cmp },
175125 try dst_mcv.address().offset((limb_len - 1) * 8).deref().mem(self, .{ .size = .qword }),
175126 .u(0),
175127 );
175128 const positive = try self.asmJccReloc(.ns, undefined);
175129
175130 try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[0].to32(), tmp_regs[0].to32());
175131 try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[1].to8(), tmp_regs[1].to8());
175132
175133 const neg_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len);
175134 try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[2].to32(), tmp_regs[2].to32());
175135 try self.asmRegisterImmediate(.{ ._r, .sh }, tmp_regs[1].to8(), .u(1));
175136 try self.asmRegisterMemory(.{ ._, .sbb }, tmp_regs[2].to64(), .{
175137 .base = .{ .frame = dst_mcv.load_frame.index },
175138 .mod = .{ .rm = .{
175139 .size = .qword,
175140 .index = tmp_regs[0].to64(),
175141 .scale = .@"8",
175142 .disp = dst_mcv.load_frame.off,
175143 } },
175144 });
175145 try self.asmSetccRegister(.c, tmp_regs[1].to8());
175146 try self.asmMemoryRegister(.{ ._, .mov }, .{
175147 .base = .{ .frame = dst_mcv.load_frame.index },
175148 .mod = .{ .rm = .{
175149 .size = .qword,
175150 .index = tmp_regs[0].to64(),
175151 .scale = .@"8",
175152 .disp = dst_mcv.load_frame.off,
175153 } },
175154 }, tmp_regs[2].to64());
175155
175156 if (self.hasFeature(.slow_incdec)) {
175157 try self.asmRegisterImmediate(.{ ._, .add }, tmp_regs[0].to32(), .u(1));
175158 } else {
175159 try self.asmRegister(.{ ._c, .in }, tmp_regs[0].to32());
175160 }
175161 try self.asmRegisterImmediate(.{ ._, .cmp }, tmp_regs[0].to32(), .u(limb_len));
175162 _ = try self.asmJccReloc(.b, neg_loop);
175163
175164 self.performReloc(positive);
175165 break :result dst_mcv;
175166 },
175167 },
175168 .float => return self.floatSign(inst, .abs, ty_op.operand, ty),
175169 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
175170 else => null,
175171 .int => switch (ty.childType(zcu).intInfo(zcu).bits) {
175172 else => null,
175173 8 => switch (ty.vectorLen(zcu)) {
175174 else => null,
175175 1...16 => if (self.hasFeature(.avx))
175176 .{ .vp_b, .abs }
175177 else if (self.hasFeature(.ssse3))
175178 .{ .p_b, .abs }
175179 else
175180 null,
175181 17...32 => if (self.hasFeature(.avx2)) .{ .vp_b, .abs } else null,
175182 },
175183 16 => switch (ty.vectorLen(zcu)) {
175184 else => null,
175185 1...8 => if (self.hasFeature(.avx))
175186 .{ .vp_w, .abs }
175187 else if (self.hasFeature(.ssse3))
175188 .{ .p_w, .abs }
175189 else
175190 null,
175191 9...16 => if (self.hasFeature(.avx2)) .{ .vp_w, .abs } else null,
175192 },
175193 32 => switch (ty.vectorLen(zcu)) {
175194 else => null,
175195 1...4 => if (self.hasFeature(.avx))
175196 .{ .vp_d, .abs }
175197 else if (self.hasFeature(.ssse3))
175198 .{ .p_d, .abs }
175199 else
175200 null,
175201 5...8 => if (self.hasFeature(.avx2)) .{ .vp_d, .abs } else null,
175202 },
175203 },
175204 .float => return self.floatSign(inst, .abs, ty_op.operand, ty),
175205 },
175206 }) orelse return self.fail("TODO implement airAbs for {f}", .{ty.fmt(pt)});
175207174350
175208 const abi_size: u32 = @intCast(ty.abiSize(zcu));
175209 const src_mcv = try self.resolveInst(ty_op.operand);
175210 const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
175211 src_mcv.getReg().?
175212 else
175213 try self.register_manager.allocReg(inst, self.regSetForType(ty));
175214 const dst_alias = registerAlias(dst_reg, abi_size);
175215 if (src_mcv.isBase()) try self.asmRegisterMemory(
175216 mir_tag,
175217 dst_alias,
175218 try src_mcv.mem(self, .{ .size = self.memSize(ty) }),
175219 ) else try self.asmRegisterRegister(
175220 mir_tag,
175221 dst_alias,
175222 registerAlias(if (src_mcv.isRegister())
175223 src_mcv.getReg().?
175224 else
175225 try self.copyToTmpRegister(ty, src_mcv), abi_size),
175226 );
175227 break :result .{ .register = dst_reg };
175228 };
175229 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
174351 return result;
175230174352}
175231174353
175232fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {
174354fn genUnwrapErrUnionPayloadPtrMir(
174355 self: *CodeGen,
174356 maybe_inst: ?Air.Inst.Index,
174357 ptr_ty: Type,
174358 ptr_mcv: MCValue,
174359) !MCValue {
175233174360 const pt = self.pt;
175234174361 const zcu = pt.zcu;
175235 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
175236 const ty = self.typeOf(un_op);
175237 const abi_size: u32 = @intCast(ty.abiSize(zcu));
174362 const err_union_ty = ptr_ty.childType(zcu);
174363 const payload_ty = err_union_ty.errorUnionPayload(zcu);
175238174364
175239174365 const result: MCValue = result: {
175240 switch (ty.zigTypeTag(zcu)) {
175241 .float => {
175242 const float_bits = ty.floatBits(self.target);
175243 if (switch (float_bits) {
175244 16 => !self.hasFeature(.f16c),
175245 32, 64 => false,
175246 80, 128 => true,
175247 else => unreachable,
175248 }) {
175249 var sym_buf: ["__sqrt?".len]u8 = undefined;
175250 break :result try self.genCall(.{ .extern_func = .{
175251 .return_type = ty.toIntern(),
175252 .param_types = &.{ty.toIntern()},
175253 .sym = std.fmt.bufPrint(&sym_buf, "{s}sqrt{s}", .{
175254 floatLibcAbiPrefix(ty),
175255 floatLibcAbiSuffix(ty),
175256 }) catch unreachable,
175257 } }, &.{ty}, &.{.{ .air_ref = un_op }}, .{});
175258 }
175259 },
175260 else => {},
175261 }
175262
175263 const src_mcv = try self.resolveInst(un_op);
175264 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
175265 src_mcv
174366 const payload_off = codegen.errUnionPayloadOffset(payload_ty, zcu);
174367 const result_mcv: MCValue = if (maybe_inst) |inst|
174368 try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr_mcv)
175266174369 else
175267 try self.copyToRegisterWithInstTracking(inst, ty, src_mcv);
175268 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
175269 const dst_lock = self.register_manager.lockReg(dst_reg);
175270 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
175271
175272 const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(zcu)) {
175273 .float => switch (ty.floatBits(self.target)) {
175274 16 => {
175275 assert(self.hasFeature(.f16c));
175276 const mat_src_reg = if (src_mcv.isRegister())
175277 src_mcv.getReg().?
175278 else
175279 try self.copyToTmpRegister(ty, src_mcv);
175280 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, mat_src_reg.to128());
175281 try self.asmRegisterRegisterRegister(.{ .v_ss, .sqrt }, dst_reg, dst_reg, dst_reg);
175282 try self.asmRegisterRegisterImmediate(
175283 .{ .v_, .cvtps2ph },
175284 dst_reg,
175285 dst_reg,
175286 bits.RoundMode.imm(.{}),
175287 );
175288 break :result dst_mcv;
175289 },
175290 32 => if (self.hasFeature(.avx)) .{ .v_ss, .sqrt } else .{ ._ss, .sqrt },
175291 64 => if (self.hasFeature(.avx)) .{ .v_sd, .sqrt } else .{ ._sd, .sqrt },
175292 else => unreachable,
175293 },
175294 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
175295 .float => switch (ty.childType(zcu).floatBits(self.target)) {
175296 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen(zcu)) {
175297 1 => {
175298 try self.asmRegisterRegister(
175299 .{ .v_ps, .cvtph2 },
175300 dst_reg,
175301 (if (src_mcv.isRegister())
175302 src_mcv.getReg().?
175303 else
175304 try self.copyToTmpRegister(ty, src_mcv)).to128(),
175305 );
175306 try self.asmRegisterRegisterRegister(
175307 .{ .v_ss, .sqrt },
175308 dst_reg,
175309 dst_reg,
175310 dst_reg,
175311 );
175312 try self.asmRegisterRegisterImmediate(
175313 .{ .v_, .cvtps2ph },
175314 dst_reg,
175315 dst_reg,
175316 bits.RoundMode.imm(.{}),
175317 );
175318 break :result dst_mcv;
175319 },
175320 2...8 => {
175321 const wide_reg = registerAlias(dst_reg, abi_size * 2);
175322 if (src_mcv.isBase()) try self.asmRegisterMemory(
175323 .{ .v_ps, .cvtph2 },
175324 wide_reg,
175325 try src_mcv.mem(self, .{ .size = .fromSize(
175326 @intCast(@divExact(wide_reg.bitSize(), 16)),
175327 ) }),
175328 ) else try self.asmRegisterRegister(
175329 .{ .v_ps, .cvtph2 },
175330 wide_reg,
175331 (if (src_mcv.isRegister())
175332 src_mcv.getReg().?
175333 else
175334 try self.copyToTmpRegister(ty, src_mcv)).to128(),
175335 );
175336 try self.asmRegisterRegister(.{ .v_ps, .sqrt }, wide_reg, wide_reg);
175337 try self.asmRegisterRegisterImmediate(
175338 .{ .v_, .cvtps2ph },
175339 dst_reg,
175340 wide_reg,
175341 bits.RoundMode.imm(.{}),
175342 );
175343 break :result dst_mcv;
175344 },
175345 else => null,
175346 } else null,
175347 32 => switch (ty.vectorLen(zcu)) {
175348 1 => if (self.hasFeature(.avx)) .{ .v_ss, .sqrt } else .{ ._ss, .sqrt },
175349 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else .{ ._ps, .sqrt },
175350 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else null,
175351 else => null,
175352 },
175353 64 => switch (ty.vectorLen(zcu)) {
175354 1 => if (self.hasFeature(.avx)) .{ .v_sd, .sqrt } else .{ ._sd, .sqrt },
175355 2 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else .{ ._pd, .sqrt },
175356 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else null,
175357 else => null,
175358 },
175359 80, 128 => null,
175360 else => unreachable,
175361 },
175362 else => unreachable,
175363 },
175364 else => unreachable,
175365 }) orelse return self.fail("TODO implement airSqrt for {f}", .{ty.fmt(pt)});
175366 switch (mir_tag[0]) {
175367 .v_ss, .v_sd => if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
175368 mir_tag,
175369 dst_reg,
175370 dst_reg,
175371 try src_mcv.mem(self, .{ .size = .fromSize(abi_size) }),
175372 ) else try self.asmRegisterRegisterRegister(
175373 mir_tag,
175374 dst_reg,
175375 dst_reg,
175376 registerAlias(if (src_mcv.isRegister())
175377 src_mcv.getReg().?
175378 else
175379 try self.copyToTmpRegister(ty, src_mcv), abi_size),
175380 ),
175381 else => if (src_mcv.isBase()) try self.asmRegisterMemory(
175382 mir_tag,
175383 dst_reg,
175384 try src_mcv.mem(self, .{ .size = .fromSize(abi_size) }),
175385 ) else try self.asmRegisterRegister(
175386 mir_tag,
175387 dst_reg,
175388 registerAlias(if (src_mcv.isRegister())
175389 src_mcv.getReg().?
175390 else
175391 try self.copyToTmpRegister(ty, src_mcv), abi_size),
175392 ),
175393 }
175394 break :result dst_mcv;
174370 .{ .register = try self.copyToTmpRegister(ptr_ty, ptr_mcv) };
174371 try self.genBinOpMir(.{ ._, .add }, ptr_ty, result_mcv, .{ .immediate = payload_off });
174372 break :result result_mcv;
175395174373 };
175396 return self.finishAir(inst, result, .{ un_op, .none, .none });
175397}
175398174374
175399fn airUnaryMath(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
175400 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
175401 const ty = self.typeOf(un_op);
175402 var sym_buf: ["__round?".len]u8 = undefined;
175403 const result = try self.genCall(.{ .extern_func = .{
175404 .return_type = ty.toIntern(),
175405 .param_types = &.{ty.toIntern()},
175406 .sym = std.fmt.bufPrint(&sym_buf, "{s}{s}{s}", .{
175407 floatLibcAbiPrefix(ty),
175408 switch (tag) {
175409 .sin,
175410 .cos,
175411 .tan,
175412 .exp,
175413 .exp2,
175414 .log,
175415 .log2,
175416 .log10,
175417 .round,
175418 => @tagName(tag),
175419 else => unreachable,
175420 },
175421 floatLibcAbiSuffix(ty),
175422 }) catch unreachable,
175423 } }, &.{ty}, &.{.{ .air_ref = un_op }}, .{});
175424 return self.finishAir(inst, result, .{ un_op, .none, .none });
174375 return result;
175425174376}
175426174377
175427174378fn reuseOperand(
......@@ -175573,95 +174524,6 @@ fn store(
175573174524 }
175574174525}
175575174526
175576fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {
175577 const pt = self.pt;
175578 const zcu = pt.zcu;
175579 const src_ty = self.typeOf(src_air);
175580 if (src_ty.zigTypeTag(zcu) == .vector)
175581 return self.fail("TODO implement genUnOp for {f}", .{src_ty.fmt(pt)});
175582
175583 var src_mcv = try self.resolveInst(src_air);
175584 switch (src_mcv) {
175585 .eflags => |cc| switch (tag) {
175586 .not => {
175587 if (maybe_inst) |inst| if (self.reuseOperand(inst, src_air, 0, src_mcv))
175588 return .{ .eflags = cc.negate() };
175589 try self.spillEflagsIfOccupied();
175590 src_mcv = try self.resolveInst(src_air);
175591 },
175592 else => {},
175593 },
175594 else => {},
175595 }
175596
175597 const src_lock = switch (src_mcv) {
175598 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
175599 else => null,
175600 };
175601 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
175602
175603 const dst_mcv: MCValue = dst: {
175604 if (maybe_inst) |inst| if (self.reuseOperand(inst, src_air, 0, src_mcv)) break :dst src_mcv;
175605
175606 const dst_mcv = try self.allocRegOrMemAdvanced(src_ty, maybe_inst, true);
175607 try self.genCopy(src_ty, dst_mcv, src_mcv, .{});
175608 break :dst dst_mcv;
175609 };
175610 const dst_lock = switch (dst_mcv) {
175611 .register => |reg| self.register_manager.lockReg(reg),
175612 else => null,
175613 };
175614 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
175615
175616 const abi_size: u16 = @intCast(src_ty.abiSize(zcu));
175617 switch (tag) {
175618 .not => {
175619 const limb_abi_size: u16 = @min(abi_size, 8);
175620 const int_info: InternPool.Key.IntType = if (src_ty.ip_index == .bool_type)
175621 .{ .signedness = .unsigned, .bits = 1 }
175622 else
175623 src_ty.intInfo(zcu);
175624 var byte_off: i32 = 0;
175625 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {
175626 const limb_bits: u16 = @intCast(@min(switch (int_info.signedness) {
175627 .signed => abi_size * 8,
175628 .unsigned => int_info.bits,
175629 } - byte_off * 8, limb_abi_size * 8));
175630 const limb_ty = try pt.intType(int_info.signedness, limb_bits);
175631 const limb_mcv = switch (byte_off) {
175632 0 => dst_mcv,
175633 else => dst_mcv.address().offset(byte_off).deref(),
175634 };
175635
175636 if (int_info.signedness == .unsigned and self.regExtraBits(limb_ty) > 0) {
175637 const mask = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - limb_bits);
175638 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });
175639 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);
175640 }
175641 },
175642 .neg => {
175643 try self.genUnOpMir(.{ ._, .neg }, src_ty, dst_mcv);
175644 const bit_size = src_ty.intInfo(zcu).bits;
175645 if (abi_size * 8 > bit_size) {
175646 if (dst_mcv.isRegister()) {
175647 try self.truncateRegister(src_ty, dst_mcv.getReg().?);
175648 } else {
175649 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
175650 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
175651 defer self.register_manager.unlockReg(tmp_lock);
175652
175653 const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref();
175654 try self.genSetReg(tmp_reg, .usize, hi_mcv, .{});
175655 try self.truncateRegister(src_ty, tmp_reg);
175656 try self.genCopy(.usize, hi_mcv, .{ .register = tmp_reg }, .{});
175657 }
175658 }
175659 },
175660 else => unreachable,
175661 }
175662 return dst_mcv;
175663}
175664
175665174527fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
175666174528 const pt = self.pt;
175667174529 const abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu));
......@@ -176346,1679 +175208,6 @@ fn genShiftBinOpMir(
176346175208 });
176347175209}
176348175210
176349fn genBinOp(
176350 self: *CodeGen,
176351 maybe_inst: ?Air.Inst.Index,
176352 air_tag: Air.Inst.Tag,
176353 lhs_air: Air.Inst.Ref,
176354 rhs_air: Air.Inst.Ref,
176355) !MCValue {
176356 const pt = self.pt;
176357 const zcu = pt.zcu;
176358 const lhs_ty = self.typeOf(lhs_air);
176359 const rhs_ty = self.typeOf(rhs_air);
176360 const abi_size: u32 = @intCast(lhs_ty.abiSize(zcu));
176361
176362 if (lhs_ty.isRuntimeFloat()) libcall: {
176363 const float_bits = lhs_ty.floatBits(self.target);
176364 const type_needs_libcall = switch (float_bits) {
176365 16 => !self.hasFeature(.f16c),
176366 32, 64 => false,
176367 80, 128 => true,
176368 else => unreachable,
176369 };
176370 switch (air_tag) {
176371 .rem, .mod => {},
176372 else => if (!type_needs_libcall) break :libcall,
176373 }
176374 var sym_buf: ["__mod?f3".len]u8 = undefined;
176375 const sym = switch (air_tag) {
176376 .add,
176377 .sub,
176378 .mul,
176379 .div_float,
176380 .div_trunc,
176381 .div_floor,
176382 .div_exact,
176383 => std.fmt.bufPrint(&sym_buf, "__{s}{c}f3", .{
176384 @tagName(air_tag)[0..3],
176385 floatCompilerRtAbiName(float_bits),
176386 }),
176387 .rem, .mod, .min, .max => std.fmt.bufPrint(&sym_buf, "{s}f{s}{s}", .{
176388 floatLibcAbiPrefix(lhs_ty),
176389 switch (air_tag) {
176390 .rem, .mod => "mod",
176391 .min => "min",
176392 .max => "max",
176393 else => unreachable,
176394 },
176395 floatLibcAbiSuffix(lhs_ty),
176396 }),
176397 else => return self.fail("TODO implement genBinOp for {s} {f}", .{
176398 @tagName(air_tag), lhs_ty.fmt(pt),
176399 }),
176400 } catch unreachable;
176401 const result = try self.genCall(.{ .extern_func = .{
176402 .return_type = lhs_ty.toIntern(),
176403 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
176404 .sym = sym,
176405 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }, .{});
176406 return switch (air_tag) {
176407 .mod => result: {
176408 const adjusted: MCValue = if (type_needs_libcall) adjusted: {
176409 var add_sym_buf: ["__add?f3".len]u8 = undefined;
176410 break :adjusted try self.genCall(.{ .extern_func = .{
176411 .return_type = lhs_ty.toIntern(),
176412 .param_types = &.{
176413 lhs_ty.toIntern(),
176414 rhs_ty.toIntern(),
176415 },
176416 .sym = std.fmt.bufPrint(&add_sym_buf, "__add{c}f3", .{
176417 floatCompilerRtAbiName(float_bits),
176418 }) catch unreachable,
176419 } }, &.{ lhs_ty, rhs_ty }, &.{ result, .{ .air_ref = rhs_air } }, .{});
176420 } else switch (float_bits) {
176421 16, 32, 64 => adjusted: {
176422 const dst_reg = switch (result) {
176423 .register => |reg| reg,
176424 else => if (maybe_inst) |inst|
176425 (try self.copyToRegisterWithInstTracking(inst, lhs_ty, result)).register
176426 else
176427 try self.copyToTmpRegister(lhs_ty, result),
176428 };
176429 const dst_lock = self.register_manager.lockReg(dst_reg);
176430 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
176431
176432 const rhs_mcv = try self.resolveInst(rhs_air);
176433 const src_mcv: MCValue = if (float_bits == 16) src: {
176434 assert(self.hasFeature(.f16c));
176435 const tmp_reg = (try self.register_manager.allocReg(
176436 null,
176437 abi.RegisterClass.sse,
176438 )).to128();
176439 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
176440 defer self.register_manager.unlockReg(tmp_lock);
176441
176442 if (rhs_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
176443 .{ .vp_w, .insr },
176444 dst_reg,
176445 dst_reg,
176446 try rhs_mcv.mem(self, .{ .size = .word }),
176447 .u(1),
176448 ) else try self.asmRegisterRegisterRegister(
176449 .{ .vp_, .unpcklwd },
176450 dst_reg,
176451 dst_reg,
176452 (if (rhs_mcv.isRegister())
176453 rhs_mcv.getReg().?
176454 else
176455 try self.copyToTmpRegister(rhs_ty, rhs_mcv)).to128(),
176456 );
176457 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
176458 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg);
176459 break :src .{ .register = tmp_reg };
176460 } else rhs_mcv;
176461
176462 if (self.hasFeature(.avx)) {
176463 const mir_tag: Mir.Inst.FixedTag = switch (float_bits) {
176464 16, 32 => .{ .v_ss, .add },
176465 64 => .{ .v_sd, .add },
176466 else => unreachable,
176467 };
176468 if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
176469 mir_tag,
176470 dst_reg,
176471 dst_reg,
176472 try src_mcv.mem(self, .{ .size = .fromBitSize(float_bits) }),
176473 ) else try self.asmRegisterRegisterRegister(
176474 mir_tag,
176475 dst_reg,
176476 dst_reg,
176477 (if (src_mcv.isRegister())
176478 src_mcv.getReg().?
176479 else
176480 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
176481 );
176482 } else {
176483 const mir_tag: Mir.Inst.FixedTag = switch (float_bits) {
176484 32 => .{ ._ss, .add },
176485 64 => .{ ._sd, .add },
176486 else => unreachable,
176487 };
176488 if (src_mcv.isBase()) try self.asmRegisterMemory(
176489 mir_tag,
176490 dst_reg,
176491 try src_mcv.mem(self, .{ .size = .fromBitSize(float_bits) }),
176492 ) else try self.asmRegisterRegister(
176493 mir_tag,
176494 dst_reg,
176495 (if (src_mcv.isRegister())
176496 src_mcv.getReg().?
176497 else
176498 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
176499 );
176500 }
176501
176502 if (float_bits == 16) try self.asmRegisterRegisterImmediate(
176503 .{ .v_, .cvtps2ph },
176504 dst_reg,
176505 dst_reg,
176506 bits.RoundMode.imm(.{}),
176507 );
176508 break :adjusted .{ .register = dst_reg };
176509 },
176510 80, 128 => return self.fail("TODO implement genBinOp for {s} of {f}", .{
176511 @tagName(air_tag), lhs_ty.fmt(pt),
176512 }),
176513 else => unreachable,
176514 };
176515 break :result try self.genCall(.{ .extern_func = .{
176516 .return_type = lhs_ty.toIntern(),
176517 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
176518 .sym = sym,
176519 } }, &.{ lhs_ty, rhs_ty }, &.{ adjusted, .{ .air_ref = rhs_air } }, .{});
176520 },
176521 .div_trunc, .div_floor => try self.genRoundLibcall(lhs_ty, result, .{
176522 .direction = switch (air_tag) {
176523 .div_trunc => .zero,
176524 .div_floor => .down,
176525 else => unreachable,
176526 },
176527 .precision = .inexact,
176528 }),
176529 else => result,
176530 };
176531 }
176532
176533 const sse_op = switch (lhs_ty.zigTypeTag(zcu)) {
176534 else => false,
176535 .float => true,
176536 .vector => switch (lhs_ty.childType(zcu).toIntern()) {
176537 .bool_type, .u1_type => false,
176538 else => true,
176539 },
176540 };
176541 if (sse_op and ((lhs_ty.scalarType(zcu).isRuntimeFloat() and
176542 lhs_ty.scalarType(zcu).floatBits(self.target) == 80) or
176543 lhs_ty.abiSize(zcu) > self.vectorSize(.float)))
176544 return self.fail("TODO implement genBinOp for {s} {f}", .{ @tagName(air_tag), lhs_ty.fmt(pt) });
176545
176546 const maybe_mask_reg = switch (air_tag) {
176547 else => null,
176548 .rem, .mod => unreachable,
176549 .max, .min => if (lhs_ty.scalarType(zcu).isRuntimeFloat()) registerAlias(
176550 if (!self.hasFeature(.avx) and self.hasFeature(.sse4_1)) mask: {
176551 try self.register_manager.getKnownReg(.xmm0, null);
176552 break :mask .xmm0;
176553 } else try self.register_manager.allocReg(null, abi.RegisterClass.sse),
176554 abi_size,
176555 ) else null,
176556 };
176557 const mask_lock =
176558 if (maybe_mask_reg) |mask_reg| self.register_manager.lockRegAssumeUnused(mask_reg) else null;
176559 defer if (mask_lock) |lock| self.register_manager.unlockReg(lock);
176560
176561 const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(zcu) and
176562 switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
176563 .bool => false,
176564 .int => switch (air_tag) {
176565 .cmp_lt, .cmp_gte => true,
176566 else => false,
176567 },
176568 .float => switch (air_tag) {
176569 .cmp_gte, .cmp_gt => true,
176570 else => false,
176571 },
176572 else => unreachable,
176573 }) .{ rhs_air, lhs_air } else .{ lhs_air, rhs_air };
176574
176575 if (lhs_ty.isAbiInt(zcu)) for (ordered_air) |op_air| {
176576 switch (try self.resolveInst(op_air)) {
176577 .register => |op_reg| switch (op_reg.class()) {
176578 .sse => try self.register_manager.getReg(op_reg, null),
176579 else => {},
176580 },
176581 else => {},
176582 }
176583 };
176584
176585 const lhs_mcv = try self.resolveInst(ordered_air[0]);
176586 var rhs_mcv = try self.resolveInst(ordered_air[1]);
176587 switch (lhs_mcv) {
176588 .immediate => |imm| switch (imm) {
176589 0 => switch (air_tag) {
176590 .sub, .sub_wrap => return self.genUnOp(maybe_inst, .neg, ordered_air[1]),
176591 else => {},
176592 },
176593 else => {},
176594 },
176595 else => {},
176596 }
176597
176598 const is_commutative = switch (air_tag) {
176599 .add,
176600 .add_wrap,
176601 .mul,
176602 .bool_or,
176603 .bit_or,
176604 .bool_and,
176605 .bit_and,
176606 .xor,
176607 .min,
176608 .max,
176609 .cmp_eq,
176610 .cmp_neq,
176611 => true,
176612
176613 else => false,
176614 };
176615
176616 const lhs_locks: [2]?RegisterLock = switch (lhs_mcv) {
176617 .register => |lhs_reg| .{ self.register_manager.lockRegAssumeUnused(lhs_reg), null },
176618 .register_pair => |lhs_regs| locks: {
176619 const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs);
176620 break :locks .{ locks[0], locks[1] };
176621 },
176622 else => @splat(null),
176623 };
176624 defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
176625
176626 const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) {
176627 .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null },
176628 .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs),
176629 else => @splat(null),
176630 };
176631 defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
176632
176633 var flipped = false;
176634 var copied_to_dst = true;
176635 const dst_mcv: MCValue = dst: {
176636 const tracked_inst = switch (air_tag) {
176637 else => maybe_inst,
176638 .cmp_lt, .cmp_lte, .cmp_eq, .cmp_gte, .cmp_gt, .cmp_neq => null,
176639 };
176640 if (maybe_inst) |inst| {
176641 if ((!sse_op or lhs_mcv.isRegister()) and
176642 self.reuseOperandAdvanced(inst, ordered_air[0], 0, lhs_mcv, tracked_inst))
176643 break :dst lhs_mcv;
176644 if (is_commutative and (!sse_op or rhs_mcv.isRegister()) and
176645 self.reuseOperandAdvanced(inst, ordered_air[1], 1, rhs_mcv, tracked_inst))
176646 {
176647 flipped = true;
176648 break :dst rhs_mcv;
176649 }
176650 }
176651 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, tracked_inst, true);
176652 if (sse_op and lhs_mcv.isRegister() and self.hasFeature(.avx))
176653 copied_to_dst = false
176654 else
176655 try self.genCopy(lhs_ty, dst_mcv, lhs_mcv, .{});
176656 rhs_mcv = try self.resolveInst(ordered_air[1]);
176657 break :dst dst_mcv;
176658 };
176659 const dst_locks: [2]?RegisterLock = switch (dst_mcv) {
176660 .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null },
176661 .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs),
176662 else => @splat(null),
176663 };
176664 defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock);
176665
176666 const unmat_src_mcv = if (flipped) lhs_mcv else rhs_mcv;
176667 const src_mcv: MCValue = if (maybe_mask_reg) |mask_reg|
176668 if (self.hasFeature(.avx) and unmat_src_mcv.isRegister() and maybe_inst != null and
176669 self.liveness.operandDies(maybe_inst.?, if (flipped) 0 else 1)) unmat_src_mcv else src: {
176670 try self.genSetReg(mask_reg, rhs_ty, unmat_src_mcv, .{});
176671 break :src .{ .register = mask_reg };
176672 }
176673 else
176674 unmat_src_mcv;
176675 const src_locks: [2]?RegisterLock = switch (src_mcv) {
176676 .register => |src_reg| .{ self.register_manager.lockReg(src_reg), null },
176677 .register_pair => |src_regs| self.register_manager.lockRegs(2, src_regs),
176678 else => @splat(null),
176679 };
176680 defer for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock);
176681
176682 if (!sse_op) {
176683 switch (air_tag) {
176684 .add,
176685 .add_wrap,
176686 => try self.genBinOpMir(.{ ._, .add }, lhs_ty, dst_mcv, src_mcv),
176687
176688 .sub,
176689 .sub_wrap,
176690 => try self.genBinOpMir(.{ ._, .sub }, lhs_ty, dst_mcv, src_mcv),
176691
176692 .ptr_add,
176693 .ptr_sub,
176694 => {
176695 const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv);
176696 const tmp_mcv = MCValue{ .register = tmp_reg };
176697 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
176698 defer self.register_manager.unlockReg(tmp_lock);
176699
176700 const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu);
176701 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
176702 try self.genBinOpMir(
176703 switch (air_tag) {
176704 .ptr_add => .{ ._, .add },
176705 .ptr_sub => .{ ._, .sub },
176706 else => unreachable,
176707 },
176708 lhs_ty,
176709 dst_mcv,
176710 tmp_mcv,
176711 );
176712 },
176713
176714 .bool_or,
176715 .bit_or,
176716 => try self.genBinOpMir(.{ ._, .@"or" }, lhs_ty, dst_mcv, src_mcv),
176717
176718 .bool_and,
176719 .bit_and,
176720 => try self.genBinOpMir(.{ ._, .@"and" }, lhs_ty, dst_mcv, src_mcv),
176721
176722 .xor => try self.genBinOpMir(.{ ._, .xor }, lhs_ty, dst_mcv, src_mcv),
176723
176724 .min,
176725 .max,
176726 => {
176727 const resolved_src_mcv = switch (src_mcv) {
176728 else => src_mcv,
176729 .air_ref => |src_ref| try self.resolveInst(src_ref),
176730 };
176731
176732 if (abi_size > 8) {
176733 const dst_regs = switch (dst_mcv) {
176734 .register_pair => |dst_regs| dst_regs,
176735 else => dst: {
176736 const dst_regs = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp);
176737 const dst_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
176738 defer for (dst_regs_locks) |lock| self.register_manager.unlockReg(lock);
176739
176740 try self.genCopy(lhs_ty, .{ .register_pair = dst_regs }, dst_mcv, .{});
176741 break :dst dst_regs;
176742 },
176743 };
176744 const dst_regs_locks = self.register_manager.lockRegs(2, dst_regs);
176745 defer for (dst_regs_locks) |dst_lock| if (dst_lock) |lock|
176746 self.register_manager.unlockReg(lock);
176747
176748 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
176749 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
176750 defer self.register_manager.unlockReg(tmp_lock);
176751
176752 const signed = lhs_ty.isSignedInt(zcu);
176753 const cc: Condition = switch (air_tag) {
176754 .min => if (signed) .nl else .nb,
176755 .max => if (signed) .nge else .nae,
176756 else => unreachable,
176757 };
176758
176759 try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_regs[1]);
176760 if (src_mcv.isBase()) {
176761 try self.asmRegisterMemory(
176762 .{ ._, .cmp },
176763 dst_regs[0],
176764 try src_mcv.mem(self, .{ .size = .qword }),
176765 );
176766 try self.asmRegisterMemory(
176767 .{ ._, .sbb },
176768 tmp_reg,
176769 try src_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
176770 );
176771 try self.asmCmovccRegisterMemory(
176772 cc,
176773 dst_regs[0],
176774 try src_mcv.mem(self, .{ .size = .qword }),
176775 );
176776 try self.asmCmovccRegisterMemory(
176777 cc,
176778 dst_regs[1],
176779 try src_mcv.address().offset(8).deref().mem(self, .{ .size = .qword }),
176780 );
176781 } else {
176782 try self.asmRegisterRegister(
176783 .{ ._, .cmp },
176784 dst_regs[0],
176785 src_mcv.register_pair[0],
176786 );
176787 try self.asmRegisterRegister(
176788 .{ ._, .sbb },
176789 tmp_reg,
176790 src_mcv.register_pair[1],
176791 );
176792 try self.asmCmovccRegisterRegister(cc, dst_regs[0], src_mcv.register_pair[0]);
176793 try self.asmCmovccRegisterRegister(cc, dst_regs[1], src_mcv.register_pair[1]);
176794 }
176795 try self.genCopy(lhs_ty, dst_mcv, .{ .register_pair = dst_regs }, .{});
176796 } else {
176797 const mat_src_mcv: MCValue = if (switch (resolved_src_mcv) {
176798 .immediate,
176799 .eflags,
176800 .register_offset,
176801 .lea_frame,
176802 .load_nav,
176803 .lea_nav,
176804 .load_uav,
176805 .lea_uav,
176806 .load_lazy_sym,
176807 .lea_lazy_sym,
176808 .load_extern_func,
176809 .lea_extern_func,
176810 => true,
176811 .memory => |addr| std.math.cast(i32, @as(i64, @bitCast(addr))) == null,
176812 else => false,
176813 .register_pair,
176814 .register_overflow,
176815 => unreachable,
176816 })
176817 .{ .register = try self.copyToTmpRegister(rhs_ty, resolved_src_mcv) }
176818 else
176819 resolved_src_mcv;
176820 const mat_mcv_lock = switch (mat_src_mcv) {
176821 .register => |reg| self.register_manager.lockReg(reg),
176822 else => null,
176823 };
176824 defer if (mat_mcv_lock) |lock| self.register_manager.unlockReg(lock);
176825
176826 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, dst_mcv, mat_src_mcv);
176827
176828 const int_info = lhs_ty.intInfo(zcu);
176829 const cc: Condition = switch (int_info.signedness) {
176830 .unsigned => switch (air_tag) {
176831 .min => .a,
176832 .max => .b,
176833 else => unreachable,
176834 },
176835 .signed => switch (air_tag) {
176836 .min => .g,
176837 .max => .l,
176838 else => unreachable,
176839 },
176840 };
176841
176842 const cmov_abi_size = @max(@as(u32, @intCast(lhs_ty.abiSize(zcu))), 2);
176843 const tmp_reg = switch (dst_mcv) {
176844 .register => |reg| reg,
176845 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),
176846 };
176847 const tmp_lock = self.register_manager.lockReg(tmp_reg);
176848 defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock);
176849 switch (mat_src_mcv) {
176850 .none,
176851 .unreach,
176852 .dead,
176853 .undef,
176854 .immediate,
176855 .eflags,
176856 .register_pair,
176857 .register_triple,
176858 .register_quadruple,
176859 .register_offset,
176860 .register_overflow,
176861 .register_mask,
176862 .indirect_load_frame,
176863 .lea_frame,
176864 .load_nav,
176865 .lea_nav,
176866 .load_uav,
176867 .lea_uav,
176868 .load_lazy_sym,
176869 .lea_lazy_sym,
176870 .load_extern_func,
176871 .lea_extern_func,
176872 .elementwise_args,
176873 .reserved_frame,
176874 .air_ref,
176875 => unreachable,
176876 .register => |src_reg| try self.asmCmovccRegisterRegister(
176877 cc,
176878 registerAlias(tmp_reg, cmov_abi_size),
176879 registerAlias(src_reg, cmov_abi_size),
176880 ),
176881 .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory(
176882 cc,
176883 registerAlias(tmp_reg, cmov_abi_size),
176884 switch (mat_src_mcv) {
176885 .memory => |addr| .{
176886 .base = .{ .reg = .ds },
176887 .mod = .{ .rm = .{
176888 .size = .fromSize(cmov_abi_size),
176889 .disp = @intCast(@as(i64, @bitCast(addr))),
176890 } },
176891 },
176892 .indirect => |reg_off| .{
176893 .base = .{ .reg = reg_off.reg },
176894 .mod = .{ .rm = .{
176895 .size = .fromSize(cmov_abi_size),
176896 .disp = reg_off.off,
176897 } },
176898 },
176899 .load_frame => |frame_addr| .{
176900 .base = .{ .frame = frame_addr.index },
176901 .mod = .{ .rm = .{
176902 .size = .fromSize(cmov_abi_size),
176903 .disp = frame_addr.off,
176904 } },
176905 },
176906 else => unreachable,
176907 },
176908 ),
176909 }
176910 try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }, .{});
176911 }
176912 },
176913
176914 .cmp_eq, .cmp_neq => {
176915 assert(lhs_ty.isVector(zcu) and lhs_ty.childType(zcu).toIntern() == .bool_type);
176916 try self.genBinOpMir(.{ ._, .xor }, lhs_ty, dst_mcv, src_mcv);
176917 switch (air_tag) {
176918 .cmp_eq => try self.genUnOpMir(.{ ._, .not }, lhs_ty, dst_mcv),
176919 .cmp_neq => {},
176920 else => unreachable,
176921 }
176922 },
176923
176924 else => return self.fail("TODO implement genBinOp for {s} {f}", .{
176925 @tagName(air_tag), lhs_ty.fmt(pt),
176926 }),
176927 }
176928 return dst_mcv;
176929 }
176930
176931 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
176932 const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) {
176933 else => unreachable,
176934 .float => switch (lhs_ty.floatBits(self.target)) {
176935 16 => {
176936 assert(self.hasFeature(.f16c));
176937 const lhs_reg = if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);
176938
176939 const tmp_reg = (try self.register_manager.allocReg(null, abi.RegisterClass.sse)).to128();
176940 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
176941 defer self.register_manager.unlockReg(tmp_lock);
176942
176943 if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
176944 .{ .vp_w, .insr },
176945 dst_reg,
176946 lhs_reg,
176947 try src_mcv.mem(self, .{ .size = .word }),
176948 .u(1),
176949 ) else try self.asmRegisterRegisterRegister(
176950 .{ .vp_, .unpcklwd },
176951 dst_reg,
176952 lhs_reg,
176953 (if (src_mcv.isRegister())
176954 src_mcv.getReg().?
176955 else
176956 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
176957 );
176958 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
176959 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg);
176960 try self.asmRegisterRegisterRegister(
176961 switch (air_tag) {
176962 .add => .{ .v_ss, .add },
176963 .sub => .{ .v_ss, .sub },
176964 .mul => .{ .v_ss, .mul },
176965 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div },
176966 .max => .{ .v_ss, .max },
176967 .min => .{ .v_ss, .min },
176968 else => unreachable,
176969 },
176970 dst_reg,
176971 dst_reg,
176972 tmp_reg,
176973 );
176974 switch (air_tag) {
176975 .div_trunc, .div_floor => try self.asmRegisterRegisterRegisterImmediate(
176976 .{ .v_ss, .round },
176977 dst_reg,
176978 dst_reg,
176979 dst_reg,
176980 bits.RoundMode.imm(.{
176981 .direction = switch (air_tag) {
176982 .div_trunc => .zero,
176983 .div_floor => .down,
176984 else => unreachable,
176985 },
176986 .precision = .inexact,
176987 }),
176988 ),
176989 else => {},
176990 }
176991 try self.asmRegisterRegisterImmediate(
176992 .{ .v_, .cvtps2ph },
176993 dst_reg,
176994 dst_reg,
176995 bits.RoundMode.imm(.{}),
176996 );
176997 return dst_mcv;
176998 },
176999 32 => switch (air_tag) {
177000 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },
177001 .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub },
177002 .mul => if (self.hasFeature(.avx)) .{ .v_ss, .mul } else .{ ._ss, .mul },
177003 .div_float,
177004 .div_trunc,
177005 .div_floor,
177006 .div_exact,
177007 => if (self.hasFeature(.avx)) .{ .v_ss, .div } else .{ ._ss, .div },
177008 .max => if (self.hasFeature(.avx)) .{ .v_ss, .max } else .{ ._ss, .max },
177009 .min => if (self.hasFeature(.avx)) .{ .v_ss, .min } else .{ ._ss, .min },
177010 else => unreachable,
177011 },
177012 64 => switch (air_tag) {
177013 .add => if (self.hasFeature(.avx)) .{ .v_sd, .add } else .{ ._sd, .add },
177014 .sub => if (self.hasFeature(.avx)) .{ .v_sd, .sub } else .{ ._sd, .sub },
177015 .mul => if (self.hasFeature(.avx)) .{ .v_sd, .mul } else .{ ._sd, .mul },
177016 .div_float,
177017 .div_trunc,
177018 .div_floor,
177019 .div_exact,
177020 => if (self.hasFeature(.avx)) .{ .v_sd, .div } else .{ ._sd, .div },
177021 .max => if (self.hasFeature(.avx)) .{ .v_sd, .max } else .{ ._sd, .max },
177022 .min => if (self.hasFeature(.avx)) .{ .v_sd, .min } else .{ ._sd, .min },
177023 else => unreachable,
177024 },
177025 80, 128 => null,
177026 else => unreachable,
177027 },
177028 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177029 else => null,
177030 .int => switch (lhs_ty.childType(zcu).intInfo(zcu).bits) {
177031 8 => switch (lhs_ty.vectorLen(zcu)) {
177032 1...16 => switch (air_tag) {
177033 .add,
177034 .add_wrap,
177035 => if (self.hasFeature(.avx)) .{ .vp_b, .add } else .{ .p_b, .add },
177036 .sub,
177037 .sub_wrap,
177038 => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub },
177039 .bit_and => if (self.hasFeature(.avx))
177040 .{ .vp_, .@"and" }
177041 else
177042 .{ .p_, .@"and" },
177043 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
177044 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
177045 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177046 .signed => if (self.hasFeature(.avx))
177047 .{ .vp_b, .mins }
177048 else if (self.hasFeature(.sse4_1))
177049 .{ .p_b, .mins }
177050 else
177051 null,
177052 .unsigned => if (self.hasFeature(.avx))
177053 .{ .vp_b, .minu }
177054 else if (self.hasFeature(.sse4_1))
177055 .{ .p_b, .minu }
177056 else
177057 null,
177058 },
177059 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177060 .signed => if (self.hasFeature(.avx))
177061 .{ .vp_b, .maxs }
177062 else if (self.hasFeature(.sse4_1))
177063 .{ .p_b, .maxs }
177064 else
177065 null,
177066 .unsigned => if (self.hasFeature(.avx))
177067 .{ .vp_b, .maxu }
177068 else if (self.hasFeature(.sse4_1))
177069 .{ .p_b, .maxu }
177070 else
177071 null,
177072 },
177073 .cmp_lt,
177074 .cmp_lte,
177075 .cmp_gte,
177076 .cmp_gt,
177077 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177078 .signed => if (self.hasFeature(.avx))
177079 .{ .vp_b, .cmpgt }
177080 else
177081 .{ .p_b, .cmpgt },
177082 .unsigned => null,
177083 },
177084 .cmp_eq,
177085 .cmp_neq,
177086 => if (self.hasFeature(.avx)) .{ .vp_b, .cmpeq } else .{ .p_b, .cmpeq },
177087 else => null,
177088 },
177089 17...32 => switch (air_tag) {
177090 .add,
177091 .add_wrap,
177092 => if (self.hasFeature(.avx2)) .{ .vp_b, .add } else null,
177093 .sub,
177094 .sub_wrap,
177095 => if (self.hasFeature(.avx2)) .{ .vp_b, .sub } else null,
177096 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
177097 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
177098 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
177099 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177100 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null,
177101 .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null,
177102 },
177103 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177104 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null,
177105 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null,
177106 },
177107 .cmp_lt,
177108 .cmp_lte,
177109 .cmp_gte,
177110 .cmp_gt,
177111 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177112 .signed => if (self.hasFeature(.avx)) .{ .vp_b, .cmpgt } else null,
177113 .unsigned => null,
177114 },
177115 .cmp_eq,
177116 .cmp_neq,
177117 => if (self.hasFeature(.avx)) .{ .vp_b, .cmpeq } else null,
177118 else => null,
177119 },
177120 else => null,
177121 },
177122 16 => switch (lhs_ty.vectorLen(zcu)) {
177123 1...8 => switch (air_tag) {
177124 .add,
177125 .add_wrap,
177126 => if (self.hasFeature(.avx)) .{ .vp_w, .add } else .{ .p_w, .add },
177127 .sub,
177128 .sub_wrap,
177129 => if (self.hasFeature(.avx)) .{ .vp_w, .sub } else .{ .p_w, .sub },
177130 .mul,
177131 .mul_wrap,
177132 => if (self.hasFeature(.avx)) .{ .vp_w, .mull } else .{ .p_d, .mull },
177133 .bit_and => if (self.hasFeature(.avx))
177134 .{ .vp_, .@"and" }
177135 else
177136 .{ .p_, .@"and" },
177137 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
177138 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
177139 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177140 .signed => if (self.hasFeature(.avx))
177141 .{ .vp_w, .mins }
177142 else
177143 .{ .p_w, .mins },
177144 .unsigned => if (self.hasFeature(.avx))
177145 .{ .vp_w, .minu }
177146 else
177147 .{ .p_w, .minu },
177148 },
177149 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177150 .signed => if (self.hasFeature(.avx))
177151 .{ .vp_w, .maxs }
177152 else
177153 .{ .p_w, .maxs },
177154 .unsigned => if (self.hasFeature(.avx))
177155 .{ .vp_w, .maxu }
177156 else
177157 .{ .p_w, .maxu },
177158 },
177159 .cmp_lt,
177160 .cmp_lte,
177161 .cmp_gte,
177162 .cmp_gt,
177163 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177164 .signed => if (self.hasFeature(.avx))
177165 .{ .vp_w, .cmpgt }
177166 else
177167 .{ .p_w, .cmpgt },
177168 .unsigned => null,
177169 },
177170 .cmp_eq,
177171 .cmp_neq,
177172 => if (self.hasFeature(.avx)) .{ .vp_w, .cmpeq } else .{ .p_w, .cmpeq },
177173 else => null,
177174 },
177175 9...16 => switch (air_tag) {
177176 .add,
177177 .add_wrap,
177178 => if (self.hasFeature(.avx2)) .{ .vp_w, .add } else null,
177179 .sub,
177180 .sub_wrap,
177181 => if (self.hasFeature(.avx2)) .{ .vp_w, .sub } else null,
177182 .mul,
177183 .mul_wrap,
177184 => if (self.hasFeature(.avx2)) .{ .vp_w, .mull } else null,
177185 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
177186 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
177187 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
177188 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177189 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null,
177190 .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null,
177191 },
177192 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177193 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null,
177194 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null,
177195 },
177196 .cmp_lt,
177197 .cmp_lte,
177198 .cmp_gte,
177199 .cmp_gt,
177200 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177201 .signed => if (self.hasFeature(.avx)) .{ .vp_w, .cmpgt } else null,
177202 .unsigned => null,
177203 },
177204 .cmp_eq,
177205 .cmp_neq,
177206 => if (self.hasFeature(.avx)) .{ .vp_w, .cmpeq } else null,
177207 else => null,
177208 },
177209 else => null,
177210 },
177211 32 => switch (lhs_ty.vectorLen(zcu)) {
177212 1...4 => switch (air_tag) {
177213 .add,
177214 .add_wrap,
177215 => if (self.hasFeature(.avx)) .{ .vp_d, .add } else .{ .p_d, .add },
177216 .sub,
177217 .sub_wrap,
177218 => if (self.hasFeature(.avx)) .{ .vp_d, .sub } else .{ .p_d, .sub },
177219 .mul,
177220 .mul_wrap,
177221 => if (self.hasFeature(.avx))
177222 .{ .vp_d, .mull }
177223 else if (self.hasFeature(.sse4_1))
177224 .{ .p_d, .mull }
177225 else
177226 null,
177227 .bit_and => if (self.hasFeature(.avx))
177228 .{ .vp_, .@"and" }
177229 else
177230 .{ .p_, .@"and" },
177231 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
177232 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
177233 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177234 .signed => if (self.hasFeature(.avx))
177235 .{ .vp_d, .mins }
177236 else if (self.hasFeature(.sse4_1))
177237 .{ .p_d, .mins }
177238 else
177239 null,
177240 .unsigned => if (self.hasFeature(.avx))
177241 .{ .vp_d, .minu }
177242 else if (self.hasFeature(.sse4_1))
177243 .{ .p_d, .minu }
177244 else
177245 null,
177246 },
177247 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177248 .signed => if (self.hasFeature(.avx))
177249 .{ .vp_d, .maxs }
177250 else if (self.hasFeature(.sse4_1))
177251 .{ .p_d, .maxs }
177252 else
177253 null,
177254 .unsigned => if (self.hasFeature(.avx))
177255 .{ .vp_d, .maxu }
177256 else if (self.hasFeature(.sse4_1))
177257 .{ .p_d, .maxu }
177258 else
177259 null,
177260 },
177261 .cmp_lt,
177262 .cmp_lte,
177263 .cmp_gte,
177264 .cmp_gt,
177265 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177266 .signed => if (self.hasFeature(.avx))
177267 .{ .vp_d, .cmpgt }
177268 else
177269 .{ .p_d, .cmpgt },
177270 .unsigned => null,
177271 },
177272 .cmp_eq,
177273 .cmp_neq,
177274 => if (self.hasFeature(.avx)) .{ .vp_d, .cmpeq } else .{ .p_d, .cmpeq },
177275 else => null,
177276 },
177277 5...8 => switch (air_tag) {
177278 .add,
177279 .add_wrap,
177280 => if (self.hasFeature(.avx2)) .{ .vp_d, .add } else null,
177281 .sub,
177282 .sub_wrap,
177283 => if (self.hasFeature(.avx2)) .{ .vp_d, .sub } else null,
177284 .mul,
177285 .mul_wrap,
177286 => if (self.hasFeature(.avx2)) .{ .vp_d, .mull } else null,
177287 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
177288 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
177289 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
177290 .min => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177291 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null,
177292 .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null,
177293 },
177294 .max => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177295 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null,
177296 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null,
177297 },
177298 .cmp_lt,
177299 .cmp_lte,
177300 .cmp_gte,
177301 .cmp_gt,
177302 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177303 .signed => if (self.hasFeature(.avx)) .{ .vp_d, .cmpgt } else null,
177304 .unsigned => null,
177305 },
177306 .cmp_eq,
177307 .cmp_neq,
177308 => if (self.hasFeature(.avx)) .{ .vp_d, .cmpeq } else null,
177309 else => null,
177310 },
177311 else => null,
177312 },
177313 64 => switch (lhs_ty.vectorLen(zcu)) {
177314 1...2 => switch (air_tag) {
177315 .add,
177316 .add_wrap,
177317 => if (self.hasFeature(.avx)) .{ .vp_q, .add } else .{ .p_q, .add },
177318 .sub,
177319 .sub_wrap,
177320 => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub },
177321 .bit_and => if (self.hasFeature(.avx))
177322 .{ .vp_, .@"and" }
177323 else
177324 .{ .p_, .@"and" },
177325 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
177326 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
177327 .cmp_lt,
177328 .cmp_lte,
177329 .cmp_gte,
177330 .cmp_gt,
177331 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177332 .signed => if (self.hasFeature(.avx))
177333 .{ .vp_q, .cmpgt }
177334 else if (self.hasFeature(.sse4_2))
177335 .{ .p_q, .cmpgt }
177336 else
177337 null,
177338 .unsigned => null,
177339 },
177340 .cmp_eq,
177341 .cmp_neq,
177342 => if (self.hasFeature(.avx))
177343 .{ .vp_q, .cmpeq }
177344 else if (self.hasFeature(.sse4_1))
177345 .{ .p_q, .cmpeq }
177346 else
177347 null,
177348 else => null,
177349 },
177350 3...4 => switch (air_tag) {
177351 .add,
177352 .add_wrap,
177353 => if (self.hasFeature(.avx2)) .{ .vp_q, .add } else null,
177354 .sub,
177355 .sub_wrap,
177356 => if (self.hasFeature(.avx2)) .{ .vp_q, .sub } else null,
177357 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
177358 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
177359 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
177360 .cmp_eq,
177361 .cmp_neq,
177362 => if (self.hasFeature(.avx)) .{ .vp_d, .cmpeq } else null,
177363 .cmp_lt,
177364 .cmp_lte,
177365 .cmp_gt,
177366 .cmp_gte,
177367 => switch (lhs_ty.childType(zcu).intInfo(zcu).signedness) {
177368 .signed => if (self.hasFeature(.avx)) .{ .vp_d, .cmpgt } else null,
177369 .unsigned => null,
177370 },
177371 else => null,
177372 },
177373 else => null,
177374 },
177375 else => null,
177376 },
177377 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177378 16 => tag: {
177379 assert(self.hasFeature(.f16c));
177380 const lhs_reg = if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);
177381 switch (lhs_ty.vectorLen(zcu)) {
177382 1 => {
177383 const tmp_reg =
177384 (try self.register_manager.allocReg(null, abi.RegisterClass.sse)).to128();
177385 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
177386 defer self.register_manager.unlockReg(tmp_lock);
177387
177388 if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
177389 .{ .vp_w, .insr },
177390 dst_reg,
177391 lhs_reg,
177392 try src_mcv.mem(self, .{ .size = .word }),
177393 .u(1),
177394 ) else try self.asmRegisterRegisterRegister(
177395 .{ .vp_, .unpcklwd },
177396 dst_reg,
177397 lhs_reg,
177398 (if (src_mcv.isRegister())
177399 src_mcv.getReg().?
177400 else
177401 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
177402 );
177403 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
177404 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg);
177405 try self.asmRegisterRegisterRegister(
177406 switch (air_tag) {
177407 .add => .{ .v_ss, .add },
177408 .sub => .{ .v_ss, .sub },
177409 .mul => .{ .v_ss, .mul },
177410 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div },
177411 .max => .{ .v_ss, .max },
177412 .min => .{ .v_ss, .max },
177413 else => unreachable,
177414 },
177415 dst_reg,
177416 dst_reg,
177417 tmp_reg,
177418 );
177419 try self.asmRegisterRegisterImmediate(
177420 .{ .v_, .cvtps2ph },
177421 dst_reg,
177422 dst_reg,
177423 bits.RoundMode.imm(.{}),
177424 );
177425 return dst_mcv;
177426 },
177427 2 => {
177428 const tmp_reg = (try self.register_manager.allocReg(
177429 null,
177430 abi.RegisterClass.sse,
177431 )).to128();
177432 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
177433 defer self.register_manager.unlockReg(tmp_lock);
177434
177435 if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
177436 .{ .vp_d, .insr },
177437 dst_reg,
177438 lhs_reg,
177439 try src_mcv.mem(self, .{ .size = .dword }),
177440 .u(1),
177441 ) else try self.asmRegisterRegisterRegister(
177442 .{ .v_ps, .unpckl },
177443 dst_reg,
177444 lhs_reg,
177445 (if (src_mcv.isRegister())
177446 src_mcv.getReg().?
177447 else
177448 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
177449 );
177450 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg);
177451 try self.asmRegisterRegisterRegister(
177452 .{ .v_ps, .movhl },
177453 tmp_reg,
177454 dst_reg,
177455 dst_reg,
177456 );
177457 try self.asmRegisterRegisterRegister(
177458 switch (air_tag) {
177459 .add => .{ .v_ps, .add },
177460 .sub => .{ .v_ps, .sub },
177461 .mul => .{ .v_ps, .mul },
177462 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
177463 .max => .{ .v_ps, .max },
177464 .min => .{ .v_ps, .max },
177465 else => unreachable,
177466 },
177467 dst_reg,
177468 dst_reg,
177469 tmp_reg,
177470 );
177471 try self.asmRegisterRegisterImmediate(
177472 .{ .v_, .cvtps2ph },
177473 dst_reg,
177474 dst_reg,
177475 bits.RoundMode.imm(.{}),
177476 );
177477 return dst_mcv;
177478 },
177479 3...4 => {
177480 const tmp_reg = (try self.register_manager.allocReg(
177481 null,
177482 abi.RegisterClass.sse,
177483 )).to128();
177484 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
177485 defer self.register_manager.unlockReg(tmp_lock);
177486
177487 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, lhs_reg);
177488 if (src_mcv.isBase()) try self.asmRegisterMemory(
177489 .{ .v_ps, .cvtph2 },
177490 tmp_reg,
177491 try src_mcv.mem(self, .{ .size = .qword }),
177492 ) else try self.asmRegisterRegister(
177493 .{ .v_ps, .cvtph2 },
177494 tmp_reg,
177495 (if (src_mcv.isRegister())
177496 src_mcv.getReg().?
177497 else
177498 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
177499 );
177500 try self.asmRegisterRegisterRegister(
177501 switch (air_tag) {
177502 .add => .{ .v_ps, .add },
177503 .sub => .{ .v_ps, .sub },
177504 .mul => .{ .v_ps, .mul },
177505 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
177506 .max => .{ .v_ps, .max },
177507 .min => .{ .v_ps, .max },
177508 else => unreachable,
177509 },
177510 dst_reg,
177511 dst_reg,
177512 tmp_reg,
177513 );
177514 try self.asmRegisterRegisterImmediate(
177515 .{ .v_, .cvtps2ph },
177516 dst_reg,
177517 dst_reg,
177518 bits.RoundMode.imm(.{}),
177519 );
177520 return dst_mcv;
177521 },
177522 5...8 => {
177523 const tmp_reg = (try self.register_manager.allocReg(
177524 null,
177525 abi.RegisterClass.sse,
177526 )).to256();
177527 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
177528 defer self.register_manager.unlockReg(tmp_lock);
177529
177530 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), lhs_reg);
177531 if (src_mcv.isBase()) try self.asmRegisterMemory(
177532 .{ .v_ps, .cvtph2 },
177533 tmp_reg,
177534 try src_mcv.mem(self, .{ .size = .xword }),
177535 ) else try self.asmRegisterRegister(
177536 .{ .v_ps, .cvtph2 },
177537 tmp_reg,
177538 (if (src_mcv.isRegister())
177539 src_mcv.getReg().?
177540 else
177541 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
177542 );
177543 try self.asmRegisterRegisterRegister(
177544 switch (air_tag) {
177545 .add => .{ .v_ps, .add },
177546 .sub => .{ .v_ps, .sub },
177547 .mul => .{ .v_ps, .mul },
177548 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
177549 .max => .{ .v_ps, .max },
177550 .min => .{ .v_ps, .max },
177551 else => unreachable,
177552 },
177553 dst_reg.to256(),
177554 dst_reg.to256(),
177555 tmp_reg,
177556 );
177557 try self.asmRegisterRegisterImmediate(
177558 .{ .v_, .cvtps2ph },
177559 dst_reg,
177560 dst_reg.to256(),
177561 bits.RoundMode.imm(.{}),
177562 );
177563 return dst_mcv;
177564 },
177565 else => break :tag null,
177566 }
177567 },
177568 32 => switch (lhs_ty.vectorLen(zcu)) {
177569 1 => switch (air_tag) {
177570 .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add },
177571 .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub },
177572 .mul => if (self.hasFeature(.avx)) .{ .v_ss, .mul } else .{ ._ss, .mul },
177573 .div_float,
177574 .div_trunc,
177575 .div_floor,
177576 .div_exact,
177577 => if (self.hasFeature(.avx)) .{ .v_ss, .div } else .{ ._ss, .div },
177578 .max => if (self.hasFeature(.avx)) .{ .v_ss, .max } else .{ ._ss, .max },
177579 .min => if (self.hasFeature(.avx)) .{ .v_ss, .min } else .{ ._ss, .min },
177580 .cmp_lt,
177581 .cmp_lte,
177582 .cmp_eq,
177583 .cmp_gte,
177584 .cmp_gt,
177585 .cmp_neq,
177586 => if (self.hasFeature(.avx)) .{ .v_ss, .cmp } else .{ ._ss, .cmp },
177587 else => unreachable,
177588 },
177589 2...4 => switch (air_tag) {
177590 .add => if (self.hasFeature(.avx)) .{ .v_ps, .add } else .{ ._ps, .add },
177591 .sub => if (self.hasFeature(.avx)) .{ .v_ps, .sub } else .{ ._ps, .sub },
177592 .mul => if (self.hasFeature(.avx)) .{ .v_ps, .mul } else .{ ._ps, .mul },
177593 .div_float,
177594 .div_trunc,
177595 .div_floor,
177596 .div_exact,
177597 => if (self.hasFeature(.avx)) .{ .v_ps, .div } else .{ ._ps, .div },
177598 .max => if (self.hasFeature(.avx)) .{ .v_ps, .max } else .{ ._ps, .max },
177599 .min => if (self.hasFeature(.avx)) .{ .v_ps, .min } else .{ ._ps, .min },
177600 .cmp_lt,
177601 .cmp_lte,
177602 .cmp_eq,
177603 .cmp_gte,
177604 .cmp_gt,
177605 .cmp_neq,
177606 => if (self.hasFeature(.avx)) .{ .v_ps, .cmp } else .{ ._ps, .cmp },
177607 else => unreachable,
177608 },
177609 5...8 => if (self.hasFeature(.avx)) switch (air_tag) {
177610 .add => .{ .v_ps, .add },
177611 .sub => .{ .v_ps, .sub },
177612 .mul => .{ .v_ps, .mul },
177613 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div },
177614 .max => .{ .v_ps, .max },
177615 .min => .{ .v_ps, .min },
177616 .cmp_lt, .cmp_lte, .cmp_eq, .cmp_gte, .cmp_gt, .cmp_neq => .{ .v_ps, .cmp },
177617 else => unreachable,
177618 } else null,
177619 else => null,
177620 },
177621 64 => switch (lhs_ty.vectorLen(zcu)) {
177622 1 => switch (air_tag) {
177623 .add => if (self.hasFeature(.avx)) .{ .v_sd, .add } else .{ ._sd, .add },
177624 .sub => if (self.hasFeature(.avx)) .{ .v_sd, .sub } else .{ ._sd, .sub },
177625 .mul => if (self.hasFeature(.avx)) .{ .v_sd, .mul } else .{ ._sd, .mul },
177626 .div_float,
177627 .div_trunc,
177628 .div_floor,
177629 .div_exact,
177630 => if (self.hasFeature(.avx)) .{ .v_sd, .div } else .{ ._sd, .div },
177631 .max => if (self.hasFeature(.avx)) .{ .v_sd, .max } else .{ ._sd, .max },
177632 .min => if (self.hasFeature(.avx)) .{ .v_sd, .min } else .{ ._sd, .min },
177633 .cmp_lt,
177634 .cmp_lte,
177635 .cmp_eq,
177636 .cmp_gte,
177637 .cmp_gt,
177638 .cmp_neq,
177639 => if (self.hasFeature(.avx)) .{ .v_sd, .cmp } else .{ ._sd, .cmp },
177640 else => unreachable,
177641 },
177642 2 => switch (air_tag) {
177643 .add => if (self.hasFeature(.avx)) .{ .v_pd, .add } else .{ ._pd, .add },
177644 .sub => if (self.hasFeature(.avx)) .{ .v_pd, .sub } else .{ ._pd, .sub },
177645 .mul => if (self.hasFeature(.avx)) .{ .v_pd, .mul } else .{ ._pd, .mul },
177646 .div_float,
177647 .div_trunc,
177648 .div_floor,
177649 .div_exact,
177650 => if (self.hasFeature(.avx)) .{ .v_pd, .div } else .{ ._pd, .div },
177651 .max => if (self.hasFeature(.avx)) .{ .v_pd, .max } else .{ ._pd, .max },
177652 .min => if (self.hasFeature(.avx)) .{ .v_pd, .min } else .{ ._pd, .min },
177653 .cmp_lt,
177654 .cmp_lte,
177655 .cmp_eq,
177656 .cmp_gte,
177657 .cmp_gt,
177658 .cmp_neq,
177659 => if (self.hasFeature(.avx)) .{ .v_pd, .cmp } else .{ ._pd, .cmp },
177660 else => unreachable,
177661 },
177662 3...4 => if (self.hasFeature(.avx)) switch (air_tag) {
177663 .add => .{ .v_pd, .add },
177664 .sub => .{ .v_pd, .sub },
177665 .mul => .{ .v_pd, .mul },
177666 .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_pd, .div },
177667 .max => .{ .v_pd, .max },
177668 .cmp_lt, .cmp_lte, .cmp_eq, .cmp_gte, .cmp_gt, .cmp_neq => .{ .v_pd, .cmp },
177669 .min => .{ .v_pd, .min },
177670 else => unreachable,
177671 } else null,
177672 else => null,
177673 },
177674 80, 128 => null,
177675 else => unreachable,
177676 },
177677 },
177678 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177679 @tagName(air_tag), lhs_ty.fmt(pt),
177680 });
177681
177682 const lhs_copy_reg = if (maybe_mask_reg) |_| registerAlias(
177683 if (copied_to_dst) try self.copyToTmpRegister(lhs_ty, dst_mcv) else lhs_mcv.getReg().?,
177684 abi_size,
177685 ) else null;
177686 const lhs_copy_lock = if (lhs_copy_reg) |reg| self.register_manager.lockReg(reg) else null;
177687 defer if (lhs_copy_lock) |lock| self.register_manager.unlockReg(lock);
177688
177689 switch (mir_tag[1]) {
177690 else => if (self.hasFeature(.avx)) {
177691 const lhs_reg = if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);
177692 if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
177693 mir_tag,
177694 dst_reg,
177695 lhs_reg,
177696 try src_mcv.mem(self, .{ .size = switch (lhs_ty.zigTypeTag(zcu)) {
177697 else => .fromSize(abi_size),
177698 .vector => dst_reg.size(),
177699 } }),
177700 ) else try self.asmRegisterRegisterRegister(
177701 mir_tag,
177702 dst_reg,
177703 lhs_reg,
177704 registerAlias(if (src_mcv.isRegister())
177705 src_mcv.getReg().?
177706 else
177707 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
177708 );
177709 } else {
177710 assert(copied_to_dst);
177711 if (src_mcv.isBase()) try self.asmRegisterMemory(
177712 mir_tag,
177713 dst_reg,
177714 try src_mcv.mem(self, .{ .size = switch (lhs_ty.zigTypeTag(zcu)) {
177715 else => .fromSize(abi_size),
177716 .vector => dst_reg.size(),
177717 } }),
177718 ) else try self.asmRegisterRegister(
177719 mir_tag,
177720 dst_reg,
177721 registerAlias(if (src_mcv.isRegister())
177722 src_mcv.getReg().?
177723 else
177724 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
177725 );
177726 },
177727 .cmp => {
177728 const imm: Immediate = .u(switch (air_tag) {
177729 .cmp_eq => 0,
177730 .cmp_lt, .cmp_gt => 1,
177731 .cmp_lte, .cmp_gte => 2,
177732 .cmp_neq => 4,
177733 else => unreachable,
177734 });
177735 if (self.hasFeature(.avx)) {
177736 const lhs_reg =
177737 if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);
177738 if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
177739 mir_tag,
177740 dst_reg,
177741 lhs_reg,
177742 try src_mcv.mem(self, .{ .size = switch (lhs_ty.zigTypeTag(zcu)) {
177743 else => .fromSize(abi_size),
177744 .vector => dst_reg.size(),
177745 } }),
177746 imm,
177747 ) else try self.asmRegisterRegisterRegisterImmediate(
177748 mir_tag,
177749 dst_reg,
177750 lhs_reg,
177751 registerAlias(if (src_mcv.isRegister())
177752 src_mcv.getReg().?
177753 else
177754 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
177755 imm,
177756 );
177757 } else {
177758 assert(copied_to_dst);
177759 if (src_mcv.isBase()) try self.asmRegisterMemoryImmediate(
177760 mir_tag,
177761 dst_reg,
177762 try src_mcv.mem(self, .{ .size = switch (lhs_ty.zigTypeTag(zcu)) {
177763 else => .fromSize(abi_size),
177764 .vector => dst_reg.size(),
177765 } }),
177766 imm,
177767 ) else try self.asmRegisterRegisterImmediate(
177768 mir_tag,
177769 dst_reg,
177770 registerAlias(if (src_mcv.isRegister())
177771 src_mcv.getReg().?
177772 else
177773 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
177774 imm,
177775 );
177776 }
177777 },
177778 }
177779
177780 switch (air_tag) {
177781 .bit_and, .bit_or, .xor => {},
177782 .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) {
177783 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
177784
177785 try self.asmRegisterRegisterRegisterImmediate(
177786 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) {
177787 .float => switch (lhs_ty.floatBits(self.target)) {
177788 32 => .{ .v_ss, .cmp },
177789 64 => .{ .v_sd, .cmp },
177790 16, 80, 128 => null,
177791 else => unreachable,
177792 },
177793 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177794 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177795 32 => switch (lhs_ty.vectorLen(zcu)) {
177796 1 => .{ .v_ss, .cmp },
177797 2...8 => .{ .v_ps, .cmp },
177798 else => null,
177799 },
177800 64 => switch (lhs_ty.vectorLen(zcu)) {
177801 1 => .{ .v_sd, .cmp },
177802 2...4 => .{ .v_pd, .cmp },
177803 else => null,
177804 },
177805 16, 80, 128 => null,
177806 else => unreachable,
177807 },
177808 else => unreachable,
177809 },
177810 else => unreachable,
177811 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177812 @tagName(air_tag), lhs_ty.fmt(pt),
177813 }),
177814 mask_reg,
177815 rhs_copy_reg,
177816 rhs_copy_reg,
177817 bits.VexFloatPredicate.imm(.unord),
177818 );
177819 try self.asmRegisterRegisterRegisterRegister(
177820 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) {
177821 .float => switch (lhs_ty.floatBits(self.target)) {
177822 32 => .{ .v_ps, .blendv },
177823 64 => .{ .v_pd, .blendv },
177824 16, 80, 128 => null,
177825 else => unreachable,
177826 },
177827 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177828 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177829 32 => switch (lhs_ty.vectorLen(zcu)) {
177830 1...8 => .{ .v_ps, .blendv },
177831 else => null,
177832 },
177833 64 => switch (lhs_ty.vectorLen(zcu)) {
177834 1...4 => .{ .v_pd, .blendv },
177835 else => null,
177836 },
177837 16, 80, 128 => null,
177838 else => unreachable,
177839 },
177840 else => unreachable,
177841 },
177842 else => unreachable,
177843 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177844 @tagName(air_tag), lhs_ty.fmt(pt),
177845 }),
177846 dst_reg,
177847 dst_reg,
177848 lhs_copy_reg.?,
177849 mask_reg,
177850 );
177851 } else {
177852 const has_blend = self.hasFeature(.sse4_1);
177853 try self.asmRegisterRegisterImmediate(
177854 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) {
177855 .float => switch (lhs_ty.floatBits(self.target)) {
177856 32 => .{ ._ss, .cmp },
177857 64 => .{ ._sd, .cmp },
177858 16, 80, 128 => null,
177859 else => unreachable,
177860 },
177861 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177862 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177863 32 => switch (lhs_ty.vectorLen(zcu)) {
177864 1 => .{ ._ss, .cmp },
177865 2...4 => .{ ._ps, .cmp },
177866 else => null,
177867 },
177868 64 => switch (lhs_ty.vectorLen(zcu)) {
177869 1 => .{ ._sd, .cmp },
177870 2 => .{ ._pd, .cmp },
177871 else => null,
177872 },
177873 16, 80, 128 => null,
177874 else => unreachable,
177875 },
177876 else => unreachable,
177877 },
177878 else => unreachable,
177879 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177880 @tagName(air_tag), lhs_ty.fmt(pt),
177881 }),
177882 mask_reg,
177883 mask_reg,
177884 bits.SseFloatPredicate.imm(if (has_blend) .unord else .ord),
177885 );
177886 if (has_blend) try self.asmRegisterRegisterRegister(
177887 @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(zcu)) {
177888 .float => switch (lhs_ty.floatBits(self.target)) {
177889 32 => .{ ._ps, .blendv },
177890 64 => .{ ._pd, .blendv },
177891 16, 80, 128 => null,
177892 else => unreachable,
177893 },
177894 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177895 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177896 32 => switch (lhs_ty.vectorLen(zcu)) {
177897 1...4 => .{ ._ps, .blendv },
177898 else => null,
177899 },
177900 64 => switch (lhs_ty.vectorLen(zcu)) {
177901 1...2 => .{ ._pd, .blendv },
177902 else => null,
177903 },
177904 16, 80, 128 => null,
177905 else => unreachable,
177906 },
177907 else => unreachable,
177908 },
177909 else => unreachable,
177910 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177911 @tagName(air_tag), lhs_ty.fmt(pt),
177912 }),
177913 dst_reg,
177914 lhs_copy_reg.?,
177915 mask_reg,
177916 ) else {
177917 const mir_fixes = @as(?Mir.Inst.Fixes, switch (lhs_ty.zigTypeTag(zcu)) {
177918 .float => switch (lhs_ty.floatBits(self.target)) {
177919 32 => ._ps,
177920 64 => ._pd,
177921 16, 80, 128 => null,
177922 else => unreachable,
177923 },
177924 .vector => switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177925 .float => switch (lhs_ty.childType(zcu).floatBits(self.target)) {
177926 32 => switch (lhs_ty.vectorLen(zcu)) {
177927 1...4 => ._ps,
177928 else => null,
177929 },
177930 64 => switch (lhs_ty.vectorLen(zcu)) {
177931 1...2 => ._pd,
177932 else => null,
177933 },
177934 16, 80, 128 => null,
177935 else => unreachable,
177936 },
177937 else => unreachable,
177938 },
177939 else => unreachable,
177940 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177941 @tagName(air_tag), lhs_ty.fmt(pt),
177942 });
177943 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg);
177944 try self.asmRegisterRegister(.{ mir_fixes, .andn }, mask_reg, lhs_copy_reg.?);
177945 try self.asmRegisterRegister(.{ mir_fixes, .@"or" }, dst_reg, mask_reg);
177946 }
177947 },
177948 .cmp_lt, .cmp_lte, .cmp_eq, .cmp_gte, .cmp_gt, .cmp_neq => {
177949 switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
177950 .int => switch (air_tag) {
177951 .cmp_lt,
177952 .cmp_eq,
177953 .cmp_gt,
177954 => {},
177955 .cmp_lte,
177956 .cmp_gte,
177957 .cmp_neq,
177958 => {
177959 const unsigned_ty = try lhs_ty.toUnsigned(pt);
177960 const not_mcv = try self.lowerValue(try unsigned_ty.maxInt(pt, unsigned_ty));
177961 const not_mem: Memory = if (not_mcv.isBase())
177962 try not_mcv.mem(self, .{ .size = .fromSize(abi_size) })
177963 else
177964 .{ .base = .{
177965 .reg = try self.copyToTmpRegister(.usize, not_mcv.address()),
177966 }, .mod = .{ .rm = .{ .size = .fromSize(abi_size) } } };
177967 switch (mir_tag[0]) {
177968 .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory(
177969 .{ .vp_, .xor },
177970 dst_reg,
177971 dst_reg,
177972 not_mem,
177973 ),
177974 .p_b, .p_d, .p_q, .p_w => try self.asmRegisterMemory(
177975 .{ .p_, .xor },
177976 dst_reg,
177977 not_mem,
177978 ),
177979 else => unreachable,
177980 }
177981 },
177982 else => unreachable,
177983 },
177984 .float => {},
177985 else => unreachable,
177986 }
177987
177988 const gp_reg = try self.register_manager.allocReg(maybe_inst, abi.RegisterClass.gp);
177989 const gp_lock = self.register_manager.lockRegAssumeUnused(gp_reg);
177990 defer self.register_manager.unlockReg(gp_lock);
177991
177992 try self.asmRegisterRegister(switch (mir_tag[0]) {
177993 ._pd, ._sd, .p_q => .{ ._pd, .movmsk },
177994 ._ps, ._ss, .p_d => .{ ._ps, .movmsk },
177995 .p_b => .{ .p_b, .movmsk },
177996 .p_w => movmsk: {
177997 try self.asmRegisterRegister(.{ .p_b, .ackssw }, dst_reg, dst_reg);
177998 break :movmsk .{ .p_b, .movmsk };
177999 },
178000 .v_pd, .v_sd, .vp_q => .{ .v_pd, .movmsk },
178001 .v_ps, .v_ss, .vp_d => .{ .v_ps, .movmsk },
178002 .vp_b => .{ .vp_b, .movmsk },
178003 .vp_w => movmsk: {
178004 try self.asmRegisterRegisterRegister(
178005 .{ .vp_b, .ackssw },
178006 dst_reg,
178007 dst_reg,
178008 dst_reg,
178009 );
178010 break :movmsk .{ .vp_b, .movmsk };
178011 },
178012 else => unreachable,
178013 }, gp_reg.to32(), dst_reg);
178014 return .{ .register = gp_reg };
178015 },
178016 else => unreachable,
178017 }
178018
178019 return dst_mcv;
178020}
178021
178022175211fn genBinOpMir(
178023175212 self: *CodeGen,
178024175213 mir_tag: Mir.Inst.FixedTag,
......@@ -178472,168 +175661,6 @@ fn genBinOpMir(
178472175661 }
178473175662}
178474175663
178475/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.
178476/// Does not support byte-size operands.
178477fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
178478 const pt = self.pt;
178479 const abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu));
178480 try self.spillEflagsIfOccupied();
178481 switch (dst_mcv) {
178482 .none,
178483 .unreach,
178484 .dead,
178485 .undef,
178486 .immediate,
178487 .eflags,
178488 .register_offset,
178489 .register_overflow,
178490 .register_mask,
178491 .indirect_load_frame,
178492 .lea_frame,
178493 .lea_nav,
178494 .lea_uav,
178495 .lea_lazy_sym,
178496 .lea_extern_func,
178497 .elementwise_args,
178498 .reserved_frame,
178499 .air_ref,
178500 => unreachable, // unmodifiable destination
178501 .register => |dst_reg| {
178502 const alias_size = switch (abi_size) {
178503 1 => 4,
178504 else => abi_size,
178505 };
178506 const dst_alias = registerAlias(dst_reg, alias_size);
178507 const dst_lock = self.register_manager.lockReg(dst_reg);
178508 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
178509
178510 switch (abi_size) {
178511 1 => try self.asmRegisterRegister(.{ ._, .movzx }, dst_reg.to32(), dst_reg.to8()),
178512 else => {},
178513 }
178514
178515 const resolved_src_mcv = switch (src_mcv) {
178516 else => src_mcv,
178517 .air_ref => |src_ref| try self.resolveInst(src_ref),
178518 };
178519 switch (resolved_src_mcv) {
178520 .none,
178521 .unreach,
178522 .dead,
178523 .undef,
178524 .register_pair,
178525 .register_triple,
178526 .register_quadruple,
178527 .register_overflow,
178528 .register_mask,
178529 .indirect_load_frame,
178530 .elementwise_args,
178531 .reserved_frame,
178532 .air_ref,
178533 => unreachable,
178534 .register => |src_reg| {
178535 switch (abi_size) {
178536 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()),
178537 else => {},
178538 }
178539 try self.asmRegisterRegister(
178540 .{ .i_, .mul },
178541 dst_alias,
178542 registerAlias(src_reg, alias_size),
178543 );
178544 },
178545 .immediate => |imm| {
178546 if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |small| {
178547 try self.asmRegisterRegisterImmediate(.{ .i_, .mul }, dst_alias, dst_alias, .s(small));
178548 } else {
178549 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
178550 return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg });
178551 }
178552 },
178553 .register_offset,
178554 .eflags,
178555 .lea_frame,
178556 .load_nav,
178557 .lea_nav,
178558 .load_uav,
178559 .lea_uav,
178560 .load_lazy_sym,
178561 .lea_lazy_sym,
178562 .load_extern_func,
178563 .lea_extern_func,
178564 => {
178565 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
178566 switch (abi_size) {
178567 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()),
178568 else => {},
178569 }
178570 try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size));
178571 },
178572 .memory, .indirect, .load_frame => switch (abi_size) {
178573 1 => {
178574 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
178575 try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8());
178576 try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size));
178577 },
178578 else => try self.asmRegisterMemory(
178579 .{ .i_, .mul },
178580 dst_alias,
178581 switch (resolved_src_mcv) {
178582 .memory => |addr| .{
178583 .base = .{ .reg = .ds },
178584 .mod = .{ .rm = .{
178585 .size = .fromSize(abi_size),
178586 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
178587 return self.asmRegisterRegister(
178588 .{ .i_, .mul },
178589 dst_alias,
178590 registerAlias(
178591 try self.copyToTmpRegister(dst_ty, resolved_src_mcv),
178592 abi_size,
178593 ),
178594 ),
178595 } },
178596 },
178597 .indirect => |reg_off| .{
178598 .base = .{ .reg = reg_off.reg },
178599 .mod = .{ .rm = .{
178600 .size = .fromSize(abi_size),
178601 .disp = reg_off.off,
178602 } },
178603 },
178604 .load_frame => |frame_addr| .{
178605 .base = .{ .frame = frame_addr.index },
178606 .mod = .{ .rm = .{
178607 .size = .fromSize(abi_size),
178608 .disp = frame_addr.off,
178609 } },
178610 },
178611 else => unreachable,
178612 },
178613 ),
178614 },
178615 }
178616 },
178617 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented
178618 .memory,
178619 .indirect,
178620 .load_frame,
178621 .load_nav,
178622 .load_uav,
178623 .load_lazy_sym,
178624 .load_extern_func,
178625 => {
178626 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
178627 const tmp_mcv = MCValue{ .register = tmp_reg };
178628 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
178629 defer self.register_manager.unlockReg(tmp_lock);
178630
178631 try self.genIntMulComplexOpMir(dst_ty, tmp_mcv, src_mcv);
178632 try self.genCopy(dst_ty, dst_mcv, tmp_mcv, .{});
178633 },
178634 }
178635}
178636
178637175664fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
178638175665 const zcu = self.pt.zcu;
178639175666 const arg_index = for (self.args, 0..) |arg, arg_index| {
......@@ -179247,475 +176274,6 @@ fn airRetLoad(self: *CodeGen, inst: Air.Inst.Index) !void {
179247176274 try self.epilogue_relocs.append(self.gpa, jmp_reloc);
179248176275}
179249176276
179250fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !void {
179251 const pt = self.pt;
179252 const zcu = pt.zcu;
179253 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
179254 var ty = self.typeOf(bin_op.lhs);
179255 var null_compare: ?Mir.Inst.Index = null;
179256
179257 const result: Condition = result: {
179258 try self.spillEflagsIfOccupied();
179259
179260 const lhs_mcv = try self.resolveInst(bin_op.lhs);
179261 const lhs_locks: [2]?RegisterLock = switch (lhs_mcv) {
179262 .register => |lhs_reg| .{ self.register_manager.lockRegAssumeUnused(lhs_reg), null },
179263 .register_pair => |lhs_regs| locks: {
179264 const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs);
179265 break :locks .{ locks[0], locks[1] };
179266 },
179267 .register_offset => |lhs_ro| .{
179268 self.register_manager.lockRegAssumeUnused(lhs_ro.reg),
179269 null,
179270 },
179271 else => @splat(null),
179272 };
179273 defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
179274
179275 const rhs_mcv = try self.resolveInst(bin_op.rhs);
179276 const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) {
179277 .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null },
179278 .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs),
179279 .register_offset => |rhs_ro| .{ self.register_manager.lockReg(rhs_ro.reg), null },
179280 else => @splat(null),
179281 };
179282 defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
179283
179284 switch (ty.zigTypeTag(zcu)) {
179285 .float => {
179286 const float_bits = ty.floatBits(self.target);
179287 if (!switch (float_bits) {
179288 16 => self.hasFeature(.f16c),
179289 32 => self.hasFeature(.sse),
179290 64 => self.hasFeature(.sse2),
179291 80, 128 => false,
179292 else => unreachable,
179293 }) {
179294 var sym_buf: ["__???f2".len]u8 = undefined;
179295 const ret = try self.genCall(.{ .extern_func = .{
179296 .return_type = .i32_type,
179297 .param_types = &.{ ty.toIntern(), ty.toIntern() },
179298 .sym = std.fmt.bufPrint(&sym_buf, "__{s}{c}f2", .{
179299 switch (op) {
179300 .eq => "eq",
179301 .neq => "ne",
179302 .lt => "lt",
179303 .lte => "le",
179304 .gt => "gt",
179305 .gte => "ge",
179306 },
179307 floatCompilerRtAbiName(float_bits),
179308 }) catch unreachable,
179309 } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, .{});
179310 try self.genBinOpMir(.{ ._, .@"test" }, .i32, ret, ret);
179311 break :result switch (op) {
179312 .eq => .e,
179313 .neq => .ne,
179314 .lt => .l,
179315 .lte => .le,
179316 .gt => .g,
179317 .gte => .ge,
179318 };
179319 }
179320 },
179321 .optional => if (!ty.optionalReprIsPayload(zcu)) {
179322 const opt_ty = ty;
179323 const opt_abi_size: u31 = @intCast(opt_ty.abiSize(zcu));
179324 ty = opt_ty.optionalChild(zcu);
179325 const payload_abi_size: u31 = @intCast(ty.abiSize(zcu));
179326
179327 const temp_lhs_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
179328 const temp_lhs_lock = self.register_manager.lockRegAssumeUnused(temp_lhs_reg);
179329 defer self.register_manager.unlockReg(temp_lhs_lock);
179330
179331 if (lhs_mcv.isBase()) try self.asmRegisterMemory(
179332 .{ ._, .mov },
179333 temp_lhs_reg.to8(),
179334 try lhs_mcv.address().offset(payload_abi_size).deref().mem(self, .{ .size = .byte }),
179335 ) else {
179336 try self.genSetReg(temp_lhs_reg, opt_ty, lhs_mcv, .{});
179337 try self.asmRegisterImmediate(
179338 .{ ._r, .sh },
179339 registerAlias(temp_lhs_reg, opt_abi_size),
179340 .u(payload_abi_size * 8),
179341 );
179342 }
179343
179344 const payload_compare = payload_compare: {
179345 if (rhs_mcv.isBase()) {
179346 const rhs_mem =
179347 try rhs_mcv.address().offset(payload_abi_size).deref().mem(self, .{ .size = .byte });
179348 try self.asmMemoryRegister(.{ ._, .@"test" }, rhs_mem, temp_lhs_reg.to8());
179349 const payload_compare = try self.asmJccReloc(.nz, undefined);
179350 try self.asmRegisterMemory(.{ ._, .cmp }, temp_lhs_reg.to8(), rhs_mem);
179351 break :payload_compare payload_compare;
179352 }
179353
179354 const temp_rhs_reg = try self.copyToTmpRegister(opt_ty, rhs_mcv);
179355 const temp_rhs_lock = self.register_manager.lockRegAssumeUnused(temp_rhs_reg);
179356 defer self.register_manager.unlockReg(temp_rhs_lock);
179357
179358 try self.asmRegisterImmediate(
179359 .{ ._r, .sh },
179360 registerAlias(temp_rhs_reg, opt_abi_size),
179361 .u(payload_abi_size * 8),
179362 );
179363 try self.asmRegisterRegister(
179364 .{ ._, .@"test" },
179365 temp_lhs_reg.to8(),
179366 temp_rhs_reg.to8(),
179367 );
179368 const payload_compare = try self.asmJccReloc(.nz, undefined);
179369 try self.asmRegisterRegister(
179370 .{ ._, .cmp },
179371 temp_lhs_reg.to8(),
179372 temp_rhs_reg.to8(),
179373 );
179374 break :payload_compare payload_compare;
179375 };
179376 null_compare = try self.asmJmpReloc(undefined);
179377 self.performReloc(payload_compare);
179378 },
179379 else => {},
179380 }
179381
179382 switch (ty.zigTypeTag(zcu)) {
179383 else => {
179384 const abi_size: u16 = @intCast(ty.abiSize(zcu));
179385 const may_flip: enum {
179386 may_flip,
179387 must_flip,
179388 must_not_flip,
179389 } = if (abi_size > 8) switch (op) {
179390 .lt, .gte => .must_not_flip,
179391 .lte, .gt => .must_flip,
179392 .eq, .neq => .may_flip,
179393 } else .may_flip;
179394
179395 const flipped = switch (may_flip) {
179396 .may_flip => !lhs_mcv.isRegister() and !lhs_mcv.isBase(),
179397 .must_flip => true,
179398 .must_not_flip => false,
179399 };
179400 const unmat_dst_mcv = if (flipped) rhs_mcv else lhs_mcv;
179401 const dst_mcv = if (unmat_dst_mcv.isRegister() or
179402 (abi_size <= 8 and unmat_dst_mcv.isBase())) unmat_dst_mcv else dst: {
179403 const dst_mcv = try self.allocTempRegOrMem(ty, true);
179404 try self.genCopy(ty, dst_mcv, unmat_dst_mcv, .{});
179405 break :dst dst_mcv;
179406 };
179407 const dst_lock =
179408 if (dst_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
179409 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
179410
179411 const src_mcv = try self.resolveInst(if (flipped) bin_op.lhs else bin_op.rhs);
179412 const src_lock =
179413 if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
179414 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
179415
179416 break :result .fromCompareOperator(
179417 if (ty.isAbiInt(zcu)) ty.intInfo(zcu).signedness else .unsigned,
179418 result_op: {
179419 const flipped_op = if (flipped) op.reverse() else op;
179420 if (abi_size > 8) switch (flipped_op) {
179421 .lt, .gte => {},
179422 .lte, .gt => unreachable,
179423 .eq, .neq => {
179424 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
179425
179426 const resolved_dst_mcv = switch (dst_mcv) {
179427 else => dst_mcv,
179428 .air_ref => |dst_ref| try self.resolveInst(dst_ref),
179429 };
179430 const dst_info: OpInfo = switch (resolved_dst_mcv) {
179431 .none,
179432 .unreach,
179433 .dead,
179434 .undef,
179435 .immediate,
179436 .eflags,
179437 .register_offset,
179438 .register_overflow,
179439 .register_mask,
179440 .indirect,
179441 .lea_frame,
179442 .lea_nav,
179443 .lea_uav,
179444 .lea_lazy_sym,
179445 .lea_extern_func,
179446 .elementwise_args,
179447 .reserved_frame,
179448 .air_ref,
179449 => unreachable,
179450 .register,
179451 .register_pair,
179452 .register_triple,
179453 .register_quadruple,
179454 .load_frame,
179455 => null,
179456 .memory,
179457 .load_nav,
179458 .load_uav,
179459 .load_lazy_sym,
179460 .load_extern_func,
179461 => dst: {
179462 switch (resolved_dst_mcv) {
179463 .memory => |addr| if (std.math.cast(
179464 i32,
179465 @as(i64, @bitCast(addr)),
179466 ) != null and std.math.cast(
179467 i32,
179468 @as(i64, @bitCast(addr)) + abi_size - 8,
179469 ) != null) break :dst null,
179470 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
179471 else => unreachable,
179472 }
179473
179474 const dst_addr_reg = (try self.register_manager.allocReg(
179475 null,
179476 abi.RegisterClass.gp,
179477 )).to64();
179478 const dst_addr_lock =
179479 self.register_manager.lockRegAssumeUnused(dst_addr_reg);
179480 errdefer self.register_manager.unlockReg(dst_addr_lock);
179481
179482 try self.genSetReg(dst_addr_reg, .usize, resolved_dst_mcv.address(), .{});
179483 break :dst .{
179484 .addr_reg = dst_addr_reg,
179485 .addr_lock = dst_addr_lock,
179486 };
179487 },
179488 };
179489 defer if (dst_info) |info| self.register_manager.unlockReg(info.addr_lock);
179490
179491 const resolved_src_mcv = switch (src_mcv) {
179492 else => src_mcv,
179493 .air_ref => |src_ref| try self.resolveInst(src_ref),
179494 };
179495 const src_info: OpInfo = switch (resolved_src_mcv) {
179496 .none,
179497 .unreach,
179498 .dead,
179499 .undef,
179500 .immediate,
179501 .eflags,
179502 .register,
179503 .register_offset,
179504 .register_overflow,
179505 .register_mask,
179506 .indirect,
179507 .lea_frame,
179508 .lea_nav,
179509 .lea_uav,
179510 .lea_lazy_sym,
179511 .lea_extern_func,
179512 .elementwise_args,
179513 .reserved_frame,
179514 .air_ref,
179515 => unreachable,
179516 .register_pair,
179517 .register_triple,
179518 .register_quadruple,
179519 .load_frame,
179520 => null,
179521 .memory,
179522 .load_nav,
179523 .load_uav,
179524 .load_lazy_sym,
179525 .load_extern_func,
179526 => src: {
179527 switch (resolved_src_mcv) {
179528 .memory => |addr| if (std.math.cast(
179529 i32,
179530 @as(i64, @bitCast(addr)),
179531 ) != null and std.math.cast(
179532 i32,
179533 @as(i64, @bitCast(addr)) + abi_size - 8,
179534 ) != null) break :src null,
179535 .load_nav, .load_uav, .load_lazy_sym, .load_extern_func => {},
179536 else => unreachable,
179537 }
179538
179539 const src_addr_reg = (try self.register_manager.allocReg(
179540 null,
179541 abi.RegisterClass.gp,
179542 )).to64();
179543 const src_addr_lock =
179544 self.register_manager.lockRegAssumeUnused(src_addr_reg);
179545 errdefer self.register_manager.unlockReg(src_addr_lock);
179546
179547 try self.genSetReg(src_addr_reg, .usize, resolved_src_mcv.address(), .{});
179548 break :src .{
179549 .addr_reg = src_addr_reg,
179550 .addr_lock = src_addr_lock,
179551 };
179552 },
179553 };
179554 defer if (src_info) |info|
179555 self.register_manager.unlockReg(info.addr_lock);
179556
179557 const regs = try self.register_manager.allocRegs(2, @splat(null), abi.RegisterClass.gp);
179558 const acc_reg = regs[0].to64();
179559 const locks = self.register_manager.lockRegsAssumeUnused(2, regs);
179560 defer for (locks) |lock| self.register_manager.unlockReg(lock);
179561
179562 const limbs_len = std.math.divCeil(u16, abi_size, 8) catch unreachable;
179563 var limb_i: u16 = 0;
179564 while (limb_i < limbs_len) : (limb_i += 1) {
179565 const off = limb_i * 8;
179566 const tmp_reg = regs[@min(limb_i, 1)].to64();
179567
179568 try self.genSetReg(tmp_reg, .usize, if (dst_info) |info| .{
179569 .indirect = .{ .reg = info.addr_reg, .off = off },
179570 } else switch (resolved_dst_mcv) {
179571 inline .register_pair,
179572 .register_triple,
179573 .register_quadruple,
179574 => |dst_regs| .{ .register = dst_regs[limb_i] },
179575 .memory => |dst_addr| .{
179576 .memory = @bitCast(@as(i64, @bitCast(dst_addr)) + off),
179577 },
179578 .indirect => |reg_off| .{ .indirect = .{
179579 .reg = reg_off.reg,
179580 .off = reg_off.off + off,
179581 } },
179582 .load_frame => |frame_addr| .{ .load_frame = .{
179583 .index = frame_addr.index,
179584 .off = frame_addr.off + off,
179585 } },
179586 else => unreachable,
179587 }, .{});
179588
179589 try self.genBinOpMir(
179590 .{ ._, .xor },
179591 .usize,
179592 .{ .register = tmp_reg },
179593 if (src_info) |info| .{
179594 .indirect = .{ .reg = info.addr_reg, .off = off },
179595 } else switch (resolved_src_mcv) {
179596 inline .register_pair,
179597 .register_triple,
179598 .register_quadruple,
179599 => |src_regs| .{ .register = src_regs[limb_i] },
179600 .memory => |src_addr| .{
179601 .memory = @bitCast(@as(i64, @bitCast(src_addr)) + off),
179602 },
179603 .indirect => |reg_off| .{ .indirect = .{
179604 .reg = reg_off.reg,
179605 .off = reg_off.off + off,
179606 } },
179607 .load_frame => |frame_addr| .{ .load_frame = .{
179608 .index = frame_addr.index,
179609 .off = frame_addr.off + off,
179610 } },
179611 else => unreachable,
179612 },
179613 );
179614
179615 if (limb_i > 0)
179616 try self.asmRegisterRegister(.{ ._, .@"or" }, acc_reg, tmp_reg);
179617 }
179618 assert(limbs_len >= 2); // use flags from or
179619 break :result_op flipped_op;
179620 },
179621 };
179622 try self.genBinOpMir(.{ ._, .cmp }, ty, dst_mcv, src_mcv);
179623 break :result_op flipped_op;
179624 },
179625 );
179626 },
179627 .float => {
179628 const flipped = switch (op) {
179629 .lt, .lte => true,
179630 .eq, .gte, .gt, .neq => false,
179631 };
179632
179633 const dst_mcv = if (flipped) rhs_mcv else lhs_mcv;
179634 const dst_reg = if (dst_mcv.isRegister())
179635 dst_mcv.getReg().?
179636 else
179637 try self.copyToTmpRegister(ty, dst_mcv);
179638 const dst_lock = self.register_manager.lockReg(dst_reg);
179639 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
179640 const src_mcv = if (flipped) lhs_mcv else rhs_mcv;
179641
179642 switch (ty.floatBits(self.target)) {
179643 16 => {
179644 assert(self.hasFeature(.f16c));
179645 const tmp1_reg =
179646 (try self.register_manager.allocReg(null, abi.RegisterClass.sse)).to128();
179647 const tmp1_mcv = MCValue{ .register = tmp1_reg };
179648 const tmp1_lock = self.register_manager.lockRegAssumeUnused(tmp1_reg);
179649 defer self.register_manager.unlockReg(tmp1_lock);
179650
179651 const tmp2_reg =
179652 (try self.register_manager.allocReg(null, abi.RegisterClass.sse)).to128();
179653 const tmp2_mcv = MCValue{ .register = tmp2_reg };
179654 const tmp2_lock = self.register_manager.lockRegAssumeUnused(tmp2_reg);
179655 defer self.register_manager.unlockReg(tmp2_lock);
179656
179657 if (src_mcv.isBase()) try self.asmRegisterRegisterMemoryImmediate(
179658 .{ .vp_w, .insr },
179659 tmp1_reg,
179660 dst_reg.to128(),
179661 try src_mcv.mem(self, .{ .size = .word }),
179662 .u(1),
179663 ) else try self.asmRegisterRegisterRegister(
179664 .{ .vp_, .unpcklwd },
179665 tmp1_reg,
179666 dst_reg.to128(),
179667 (if (src_mcv.isRegister())
179668 src_mcv.getReg().?
179669 else
179670 try self.copyToTmpRegister(ty, src_mcv)).to128(),
179671 );
179672 try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, tmp1_reg, tmp1_reg);
179673 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg);
179674 try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv);
179675 },
179676 32 => try self.genBinOpMir(
179677 .{ ._ss, .ucomi },
179678 ty,
179679 .{ .register = dst_reg },
179680 src_mcv,
179681 ),
179682 64 => try self.genBinOpMir(
179683 .{ ._sd, .ucomi },
179684 ty,
179685 .{ .register = dst_reg },
179686 src_mcv,
179687 ),
179688 else => unreachable,
179689 }
179690
179691 break :result switch (if (flipped) op.reverse() else op) {
179692 .lt, .lte => unreachable, // required to have been canonicalized to gt(e)
179693 .gt => .a,
179694 .gte => .ae,
179695 .eq => .z_and_np,
179696 .neq => .nz_or_p,
179697 };
179698 },
179699 }
179700 };
179701
179702 if (null_compare) |reloc| self.performReloc(reloc);
179703 self.eflags_inst = inst;
179704 return self.finishAir(inst, .{ .eflags = result }, .{ bin_op.lhs, bin_op.rhs, .none });
179705}
179706
179707fn airCmpVector(self: *CodeGen, inst: Air.Inst.Index) !void {
179708 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
179709 const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
179710 const dst_mcv = try self.genBinOp(
179711 inst,
179712 .fromCmpOp(extra.compareOperator(), false),
179713 extra.lhs,
179714 extra.rhs,
179715 );
179716 return self.finishAir(inst, dst_mcv, .{ extra.lhs, extra.rhs, .none });
179717}
179718
179719176277fn airTry(self: *CodeGen, inst: Air.Inst.Index) !void {
179720176278 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
179721176279 const extra = self.air.extraData(Air.Try, pl_op.payload);
......@@ -181223,16 +177781,13 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
181223177781 .@".cfi_escape" => error.InvalidInstruction,
181224177782 else => unreachable,
181225177783 } else self.asmOps(mnem_fixed_tag, ops)) catch |err| switch (err) {
181226 error.InvalidInstruction => return self.fail(
181227 "invalid instruction: '{s} {s} {s} {s} {s}'",
181228 .{
181229 mnem_str,
181230 @tagName(ops[0]),
181231 @tagName(ops[1]),
181232 @tagName(ops[2]),
181233 @tagName(ops[3]),
181234 },
181235 ),
177784 error.InvalidInstruction => return self.fail("invalid instruction: '{s} {s} {s} {s} {s}'", .{
177785 mnem_str,
177786 @tagName(ops[0]),
177787 @tagName(ops[1]),
177788 @tagName(ops[2]),
177789 @tagName(ops[3]),
177790 }),
181236177791 else => |e| return e,
181237177792 };
181238177793 }
......@@ -182904,183 +179459,6 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void {
182904179459 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
182905179460}
182906179461
182907fn airArrayToSlice(self: *CodeGen, inst: Air.Inst.Index) !void {
182908 const pt = self.pt;
182909 const zcu = pt.zcu;
182910 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
182911
182912 const slice_ty = self.typeOfIndex(inst);
182913 const ptr_ty = self.typeOf(ty_op.operand);
182914 const ptr = try self.resolveInst(ty_op.operand);
182915 const array_ty = ptr_ty.childType(zcu);
182916 const array_len = array_ty.arrayLen(zcu);
182917
182918 const frame_index = try self.allocFrameIndex(.initSpill(slice_ty, zcu));
182919 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{});
182920 try self.genSetMem(
182921 .{ .frame = frame_index },
182922 @intCast(ptr_ty.abiSize(zcu)),
182923 .usize,
182924 .{ .immediate = array_len },
182925 .{},
182926 );
182927
182928 const result = MCValue{ .load_frame = .{ .index = frame_index } };
182929 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
182930}
182931
182932fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {
182933 const pt = self.pt;
182934 const zcu = pt.zcu;
182935 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
182936
182937 const dst_ty = self.typeOfIndex(inst);
182938 const dst_bits = dst_ty.floatBits(self.target);
182939
182940 const src_ty = self.typeOf(ty_op.operand);
182941 const src_bits: u32 = @intCast(src_ty.bitSize(zcu));
182942 const src_signedness =
182943 if (src_ty.isAbiInt(zcu)) src_ty.intInfo(zcu).signedness else .unsigned;
182944 const src_size = std.math.divCeil(u32, @max(switch (src_signedness) {
182945 .signed => src_bits,
182946 .unsigned => src_bits + 1,
182947 }, 32), 8) catch unreachable;
182948
182949 const result = result: {
182950 if (switch (dst_bits) {
182951 16, 80, 128 => true,
182952 32, 64 => src_size > 8,
182953 else => unreachable,
182954 }) {
182955 if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {f} to {f}", .{
182956 src_ty.fmt(pt), dst_ty.fmt(pt),
182957 });
182958
182959 var sym_buf: ["__floatun?i?f".len]u8 = undefined;
182960 break :result try self.genCall(.{ .extern_func = .{
182961 .return_type = dst_ty.toIntern(),
182962 .param_types = &.{src_ty.toIntern()},
182963 .sym = std.fmt.bufPrint(&sym_buf, "__float{s}{c}i{c}f", .{
182964 switch (src_signedness) {
182965 .signed => "",
182966 .unsigned => "un",
182967 },
182968 intCompilerRtAbiName(src_bits),
182969 floatCompilerRtAbiName(dst_bits),
182970 }) catch unreachable,
182971 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
182972 }
182973
182974 const src_mcv = try self.resolveInst(ty_op.operand);
182975 const src_reg = if (src_mcv.isRegister())
182976 src_mcv.getReg().?
182977 else
182978 try self.copyToTmpRegister(src_ty, src_mcv);
182979 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
182980 defer self.register_manager.unlockReg(src_lock);
182981
182982 if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg);
182983
182984 const dst_reg = try self.register_manager.allocReg(inst, self.regSetForType(dst_ty));
182985 const dst_mcv = MCValue{ .register = dst_reg };
182986 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
182987 defer self.register_manager.unlockReg(dst_lock);
182988
182989 const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(zcu)) {
182990 .float => switch (dst_ty.floatBits(self.target)) {
182991 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },
182992 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },
182993 16, 80, 128 => null,
182994 else => unreachable,
182995 },
182996 else => null,
182997 }) orelse return self.fail("TODO implement airFloatFromInt from {f} to {f}", .{
182998 src_ty.fmt(pt), dst_ty.fmt(pt),
182999 });
183000 const dst_alias = dst_reg.to128();
183001 const src_alias = registerAlias(src_reg, src_size);
183002 switch (mir_tag[0]) {
183003 .v_ss, .v_sd => try self.asmRegisterRegisterRegister(mir_tag, dst_alias, dst_alias, src_alias),
183004 else => try self.asmRegisterRegister(mir_tag, dst_alias, src_alias),
183005 }
183006
183007 break :result dst_mcv;
183008 };
183009 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
183010}
183011
183012fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void {
183013 const pt = self.pt;
183014 const zcu = pt.zcu;
183015 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
183016
183017 const dst_ty = self.typeOfIndex(inst);
183018 const dst_bits: u32 = @intCast(dst_ty.bitSize(zcu));
183019 const dst_signedness =
183020 if (dst_ty.isAbiInt(zcu)) dst_ty.intInfo(zcu).signedness else .unsigned;
183021 const dst_size = std.math.divCeil(u32, @max(switch (dst_signedness) {
183022 .signed => dst_bits,
183023 .unsigned => dst_bits + 1,
183024 }, 32), 8) catch unreachable;
183025
183026 const src_ty = self.typeOf(ty_op.operand);
183027 const src_bits = src_ty.floatBits(self.target);
183028
183029 const result = result: {
183030 if (switch (src_bits) {
183031 16, 80, 128 => true,
183032 32, 64 => dst_size > 8,
183033 else => unreachable,
183034 }) {
183035 if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {f} to {f}", .{
183036 src_ty.fmt(pt), dst_ty.fmt(pt),
183037 });
183038
183039 var sym_buf: ["__fixuns?f?i".len]u8 = undefined;
183040 break :result try self.genCall(.{ .extern_func = .{
183041 .return_type = dst_ty.toIntern(),
183042 .param_types = &.{src_ty.toIntern()},
183043 .sym = std.fmt.bufPrint(&sym_buf, "__fix{s}{c}f{c}i", .{
183044 switch (dst_signedness) {
183045 .signed => "",
183046 .unsigned => "uns",
183047 },
183048 floatCompilerRtAbiName(src_bits),
183049 intCompilerRtAbiName(dst_bits),
183050 }) catch unreachable,
183051 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
183052 }
183053
183054 const src_mcv = try self.resolveInst(ty_op.operand);
183055 const src_reg = if (src_mcv.isRegister())
183056 src_mcv.getReg().?
183057 else
183058 try self.copyToTmpRegister(src_ty, src_mcv);
183059 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
183060 defer self.register_manager.unlockReg(src_lock);
183061
183062 const dst_reg = try self.register_manager.allocReg(inst, self.regSetForType(dst_ty));
183063 const dst_mcv = MCValue{ .register = dst_reg };
183064 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
183065 defer self.register_manager.unlockReg(dst_lock);
183066
183067 try self.asmRegisterRegister(
183068 switch (src_bits) {
183069 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },
183070 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },
183071 else => unreachable,
183072 },
183073 registerAlias(dst_reg, dst_size),
183074 src_reg.to128(),
183075 );
183076
183077 if (dst_bits < dst_size * 8) try self.truncateRegister(dst_ty, dst_reg);
183078
183079 break :result dst_mcv;
183080 };
183081 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
183082}
183083
183084179462fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void {
183085179463 const pt = self.pt;
183086179464 const zcu = pt.zcu;
......@@ -183747,331 +180125,46 @@ fn airSplat(self: *CodeGen, inst: Air.Inst.Index) !void {
183747180125 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
183748180126 const vector_ty = self.typeOfIndex(inst);
183749180127 const vector_len = vector_ty.vectorLen(zcu);
183750 const dst_rc = self.regSetForType(vector_ty);
183751180128 const scalar_ty = self.typeOf(ty_op.operand);
183752180129
183753180130 const result: MCValue = result: {
183754 switch (scalar_ty.zigTypeTag(zcu)) {
183755 else => {},
183756 .bool => {
183757 const regs =
183758 try self.register_manager.allocRegs(2, .{ inst, null }, abi.RegisterClass.gp);
183759 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, regs);
183760 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
183761
183762 try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }, .{});
183763 try self.genSetReg(
183764 regs[1],
183765 vector_ty,
183766 .{ .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - vector_len) },
183767 .{},
183768 );
183769 const src_mcv = try self.resolveInst(ty_op.operand);
183770 const abi_size = @max(std.math.divCeil(u32, vector_len, 8) catch unreachable, 4);
183771 try self.asmCmovccRegisterRegister(
183772 switch (src_mcv) {
183773 .eflags => |cc| cc,
183774 .register => |src_reg| cc: {
183775 try self.asmRegisterImmediate(.{ ._, .@"test" }, src_reg.to8(), .u(1));
183776 break :cc .nz;
183777 },
183778 else => cc: {
183779 try self.asmMemoryImmediate(
183780 .{ ._, .@"test" },
183781 try src_mcv.mem(self, .{ .size = .byte }),
183782 .u(1),
183783 );
183784 break :cc .nz;
183785 },
183786 },
183787 registerAlias(regs[0], abi_size),
183788 registerAlias(regs[1], abi_size),
183789 );
183790 break :result .{ .register = regs[0] };
183791 },
183792 .int => if (self.hasFeature(.avx2)) avx2: {
183793 const mir_tag = @as(?Mir.Inst.FixedTag, switch (scalar_ty.intInfo(zcu).bits) {
183794 else => null,
183795 1...8 => switch (vector_len) {
183796 else => null,
183797 1...32 => .{ .vp_b, .broadcast },
183798 },
183799 9...16 => switch (vector_len) {
183800 else => null,
183801 1...16 => .{ .vp_w, .broadcast },
183802 },
183803 17...32 => switch (vector_len) {
183804 else => null,
183805 1...8 => .{ .vp_d, .broadcast },
183806 },
183807 33...64 => switch (vector_len) {
183808 else => null,
183809 1...4 => .{ .vp_q, .broadcast },
183810 },
183811 65...128 => switch (vector_len) {
183812 else => null,
183813 1...2 => .{ .v_i128, .broadcast },
183814 },
183815 }) orelse break :avx2;
183816
183817 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.sse);
183818 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
183819 defer self.register_manager.unlockReg(dst_lock);
183820
183821 const src_mcv = try self.resolveInst(ty_op.operand);
183822 if (src_mcv.isBase()) try self.asmRegisterMemory(
183823 mir_tag,
183824 registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu))),
183825 try src_mcv.mem(self, .{ .size = self.memSize(scalar_ty) }),
183826 ) else {
183827 if (mir_tag[0] == .v_i128) break :avx2;
183828 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});
183829 try self.asmRegisterRegister(
183830 mir_tag,
183831 registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu))),
183832 registerAlias(dst_reg, @intCast(scalar_ty.abiSize(zcu))),
183833 );
183834 }
183835 break :result .{ .register = dst_reg };
183836 } else {
183837 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.sse);
183838 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
183839 defer self.register_manager.unlockReg(dst_lock);
183840
183841 try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{});
183842 if (vector_len == 1) break :result .{ .register = dst_reg };
180131 if (scalar_ty.toIntern() != .bool_type) return self.fail("TODO implement airSplat for {f}", .{
180132 vector_ty.fmt(pt),
180133 });
180134 const regs =
180135 try self.register_manager.allocRegs(2, .{ inst, null }, abi.RegisterClass.gp);
180136 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, regs);
180137 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
183843180138
183844 const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(zcu)));
183845 const scalar_bits = scalar_ty.intInfo(zcu).bits;
183846 if (switch (scalar_bits) {
183847 1...8 => true,
183848 9...128 => false,
183849 else => unreachable,
183850 }) if (self.hasFeature(.avx)) try self.asmRegisterRegisterRegister(
183851 .{ .vp_, .unpcklbw },
183852 dst_alias,
183853 dst_alias,
183854 dst_alias,
183855 ) else try self.asmRegisterRegister(
183856 .{ .p_, .unpcklbw },
183857 dst_alias,
183858 dst_alias,
183859 );
183860 if (switch (scalar_bits) {
183861 1...8 => vector_len > 2,
183862 9...16 => true,
183863 17...128 => false,
183864 else => unreachable,
183865 }) try self.asmRegisterRegisterImmediate(
183866 .{ if (self.hasFeature(.avx)) .vp_w else .p_w, .shufl },
183867 dst_alias,
183868 dst_alias,
183869 .u(0b00_00_00_00),
183870 );
183871 if (switch (scalar_bits) {
183872 1...8 => vector_len > 4,
183873 9...16 => vector_len > 2,
183874 17...64 => true,
183875 65...128 => false,
183876 else => unreachable,
183877 }) try self.asmRegisterRegisterImmediate(
183878 .{ if (self.hasFeature(.avx)) .vp_d else .p_d, .shuf },
183879 dst_alias,
183880 dst_alias,
183881 .u(if (scalar_bits <= 64) 0b00_00_00_00 else 0b01_00_01_00),
183882 );
183883 break :result .{ .register = dst_reg };
183884 },
183885 .float => switch (scalar_ty.floatBits(self.target)) {
183886 32 => switch (vector_len) {
183887 1 => {
183888 const src_mcv = try self.resolveInst(ty_op.operand);
183889 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
183890 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
183891 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});
183892 break :result .{ .register = dst_reg };
183893 },
183894 2...4 => {
183895 const src_mcv = try self.resolveInst(ty_op.operand);
183896 if (self.hasFeature(.avx)) {
183897 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
183898 if (src_mcv.isBase()) try self.asmRegisterMemory(
183899 .{ .v_ss, .broadcast },
183900 dst_reg.to128(),
183901 try src_mcv.mem(self, .{ .size = .dword }),
183902 ) else {
183903 const src_reg = if (src_mcv.isRegister())
183904 src_mcv.getReg().?
183905 else
183906 try self.copyToTmpRegister(scalar_ty, src_mcv);
183907 try self.asmRegisterRegisterRegisterImmediate(
183908 .{ .v_ps, .shuf },
183909 dst_reg.to128(),
183910 src_reg.to128(),
183911 src_reg.to128(),
183912 .u(0),
183913 );
183914 }
183915 break :result .{ .register = dst_reg };
183916 } else {
183917 const dst_mcv = if (src_mcv.isRegister() and
183918 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
183919 src_mcv
183920 else
183921 try self.copyToRegisterWithInstTracking(inst, scalar_ty, src_mcv);
183922 const dst_reg = dst_mcv.getReg().?;
183923 try self.asmRegisterRegisterImmediate(
183924 .{ ._ps, .shuf },
183925 dst_reg.to128(),
183926 dst_reg.to128(),
183927 .u(0),
183928 );
183929 break :result dst_mcv;
183930 }
183931 },
183932 5...8 => if (self.hasFeature(.avx)) {
183933 const src_mcv = try self.resolveInst(ty_op.operand);
183934 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
183935 if (src_mcv.isBase()) try self.asmRegisterMemory(
183936 .{ .v_ss, .broadcast },
183937 dst_reg.to256(),
183938 try src_mcv.mem(self, .{ .size = .dword }),
183939 ) else {
183940 const src_reg = if (src_mcv.isRegister())
183941 src_mcv.getReg().?
183942 else
183943 try self.copyToTmpRegister(scalar_ty, src_mcv);
183944 if (self.hasFeature(.avx2)) try self.asmRegisterRegister(
183945 .{ .v_ss, .broadcast },
183946 dst_reg.to256(),
183947 src_reg.to128(),
183948 ) else {
183949 try self.asmRegisterRegisterRegisterImmediate(
183950 .{ .v_ps, .shuf },
183951 dst_reg.to128(),
183952 src_reg.to128(),
183953 src_reg.to128(),
183954 .u(0),
183955 );
183956 try self.asmRegisterRegisterRegisterImmediate(
183957 .{ .v_f128, .insert },
183958 dst_reg.to256(),
183959 dst_reg.to256(),
183960 dst_reg.to128(),
183961 .u(1),
183962 );
183963 }
183964 }
183965 break :result .{ .register = dst_reg };
183966 },
183967 else => {},
183968 },
183969 64 => switch (vector_len) {
183970 1 => {
183971 const src_mcv = try self.resolveInst(ty_op.operand);
183972 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
183973 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
183974 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});
183975 break :result .{ .register = dst_reg };
183976 },
183977 2 => {
183978 const src_mcv = try self.resolveInst(ty_op.operand);
183979 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
183980 if (self.hasFeature(.sse3)) {
183981 if (src_mcv.isBase()) try self.asmRegisterMemory(
183982 if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup },
183983 dst_reg.to128(),
183984 try src_mcv.mem(self, .{ .size = .qword }),
183985 ) else try self.asmRegisterRegister(
183986 if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup },
183987 dst_reg.to128(),
183988 (if (src_mcv.isRegister())
183989 src_mcv.getReg().?
183990 else
183991 try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(),
183992 );
183993 break :result .{ .register = dst_reg };
183994 } else try self.asmRegisterRegister(
183995 .{ ._ps, .movlh },
183996 dst_reg.to128(),
183997 (if (src_mcv.isRegister())
183998 src_mcv.getReg().?
183999 else
184000 try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(),
184001 );
184002 },
184003 3...4 => if (self.hasFeature(.avx)) {
184004 const src_mcv = try self.resolveInst(ty_op.operand);
184005 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
184006 if (src_mcv.isBase()) try self.asmRegisterMemory(
184007 .{ .v_sd, .broadcast },
184008 dst_reg.to256(),
184009 try src_mcv.mem(self, .{ .size = .qword }),
184010 ) else {
184011 const src_reg = if (src_mcv.isRegister())
184012 src_mcv.getReg().?
184013 else
184014 try self.copyToTmpRegister(scalar_ty, src_mcv);
184015 if (self.hasFeature(.avx2)) try self.asmRegisterRegister(
184016 .{ .v_sd, .broadcast },
184017 dst_reg.to256(),
184018 src_reg.to128(),
184019 ) else {
184020 try self.asmRegisterRegister(
184021 .{ .v_, .movddup },
184022 dst_reg.to128(),
184023 src_reg.to128(),
184024 );
184025 try self.asmRegisterRegisterRegisterImmediate(
184026 .{ .v_f128, .insert },
184027 dst_reg.to256(),
184028 dst_reg.to256(),
184029 dst_reg.to128(),
184030 .u(1),
184031 );
184032 }
184033 }
184034 break :result .{ .register = dst_reg };
184035 },
184036 else => {},
180139 try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }, .{});
180140 try self.genSetReg(
180141 regs[1],
180142 vector_ty,
180143 .{ .immediate = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - vector_len) },
180144 .{},
180145 );
180146 const src_mcv = try self.resolveInst(ty_op.operand);
180147 const abi_size = @max(std.math.divCeil(u32, vector_len, 8) catch unreachable, 4);
180148 try self.asmCmovccRegisterRegister(
180149 switch (src_mcv) {
180150 .eflags => |cc| cc,
180151 .register => |src_reg| cc: {
180152 try self.asmRegisterImmediate(.{ ._, .@"test" }, src_reg.to8(), .u(1));
180153 break :cc .nz;
184037180154 },
184038 128 => switch (vector_len) {
184039 1 => {
184040 const src_mcv = try self.resolveInst(ty_op.operand);
184041 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
184042 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
184043 try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{});
184044 break :result .{ .register = dst_reg };
184045 },
184046 2 => if (self.hasFeature(.avx)) {
184047 const src_mcv = try self.resolveInst(ty_op.operand);
184048 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
184049 if (src_mcv.isBase()) try self.asmRegisterMemory(
184050 .{ .v_f128, .broadcast },
184051 dst_reg.to256(),
184052 try src_mcv.mem(self, .{ .size = .xword }),
184053 ) else {
184054 const src_reg = if (src_mcv.isRegister())
184055 src_mcv.getReg().?
184056 else
184057 try self.copyToTmpRegister(scalar_ty, src_mcv);
184058 try self.asmRegisterRegisterRegisterImmediate(
184059 .{ .v_f128, .insert },
184060 dst_reg.to256(),
184061 src_reg.to256(),
184062 src_reg.to128(),
184063 .u(1),
184064 );
184065 }
184066 break :result .{ .register = dst_reg };
184067 },
184068 else => {},
180155 else => cc: {
180156 try self.asmMemoryImmediate(
180157 .{ ._, .@"test" },
180158 try src_mcv.mem(self, .{ .size = .byte }),
180159 .u(1),
180160 );
180161 break :cc .nz;
184069180162 },
184070 16, 80 => {},
184071 else => unreachable,
184072180163 },
184073 }
184074 return self.fail("TODO implement airSplat for {f}", .{vector_ty.fmt(pt)});
180164 registerAlias(regs[0], abi_size),
180165 registerAlias(regs[1], abi_size),
180166 );
180167 break :result .{ .register = regs[0] };
184075180168 };
184076180169 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
184077180170}
......@@ -185349,161 +181442,135 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {
185349181442 const result: MCValue = result: {
185350181443 switch (result_ty.zigTypeTag(zcu)) {
185351181444 .@"struct" => {
181445 if (result_ty.containerLayout(zcu) == .@"packed") return self.fail(
181446 "TODO implement airAggregateInit for {f}",
181447 .{result_ty.fmt(pt)},
181448 );
185352181449 const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu));
185353 if (result_ty.containerLayout(zcu) == .@"packed") {
185354 const loaded_struct = zcu.intern_pool.loadStructType(result_ty.toIntern());
185355 try self.genInlineMemset(
185356 .{ .lea_frame = .{ .index = frame_index } },
185357 .{ .immediate = 0 },
185358 .{ .immediate = result_ty.abiSize(zcu) },
185359 .{},
185360 );
185361 for (elements, 0..) |elem, elem_i_usize| {
185362 const elem_i: u32 = @intCast(elem_i_usize);
185363 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
185364
185365 const elem_ty = result_ty.fieldType(elem_i, zcu);
185366 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
185367 if (elem_bit_size > 64) {
185368 return self.fail(
185369 "TODO airAggregateInit implement packed structs with large fields",
185370 .{},
185371 );
185372 }
185373 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu));
185374 const elem_abi_bits = elem_abi_size * 8;
185375 const elem_off = zcu.structPackedFieldBitOffset(loaded_struct, elem_i);
185376 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
185377 const elem_bit_off = elem_off % elem_abi_bits;
185378 const elem_mcv = try self.resolveInst(elem);
185379 const elem_lock = switch (elem_mcv) {
185380 .register => |reg| self.register_manager.lockReg(reg),
185381 .immediate => |imm| lock: {
185382 if (imm == 0) continue;
185383 break :lock null;
185384 },
185385 else => null,
185386 };
185387 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
185388
185389 const elem_extra_bits = self.regExtraBits(elem_ty);
185390 {
185391 const temp_reg = try self.copyToTmpRegister(elem_ty, elem_mcv);
185392 const temp_alias = registerAlias(temp_reg, elem_abi_size);
185393 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
185394 defer self.register_manager.unlockReg(temp_lock);
185395
185396 if (elem_bit_off < elem_extra_bits) {
185397 try self.truncateRegister(elem_ty, temp_alias);
185398 }
185399 if (elem_bit_off > 0) try self.genShiftBinOpMir(
185400 .{ ._l, .sh },
185401 elem_ty,
185402 .{ .register = temp_alias },
185403 .u8,
185404 .{ .immediate = elem_bit_off },
185405 );
185406 try self.genBinOpMir(
185407 .{ ._, .@"or" },
185408 elem_ty,
185409 .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
185410 .{ .register = temp_alias },
185411 );
185412 }
185413 if (elem_bit_off > elem_extra_bits) {
185414 const temp_reg = try self.copyToTmpRegister(elem_ty, elem_mcv);
185415 const temp_alias = registerAlias(temp_reg, elem_abi_size);
185416 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
185417 defer self.register_manager.unlockReg(temp_lock);
185418
185419 if (elem_extra_bits > 0) {
185420 try self.truncateRegister(elem_ty, temp_alias);
185421 }
185422 try self.genShiftBinOpMir(
185423 .{ ._r, .sh },
185424 elem_ty,
185425 .{ .register = temp_reg },
185426 .u8,
185427 .{ .immediate = elem_abi_bits - elem_bit_off },
185428 );
185429 try self.genBinOpMir(
185430 .{ ._, .@"or" },
185431 elem_ty,
185432 .{ .load_frame = .{
185433 .index = frame_index,
185434 .off = elem_byte_off + @as(i32, @intCast(elem_abi_size)),
185435 } },
185436 .{ .register = temp_alias },
185437 );
185438 }
185439 }
185440 } else for (elements, 0..) |elem, elem_i| {
181450 const loaded_struct = zcu.intern_pool.loadStructType(result_ty.toIntern());
181451 try self.genInlineMemset(
181452 .{ .lea_frame = .{ .index = frame_index } },
181453 .{ .immediate = 0 },
181454 .{ .immediate = result_ty.abiSize(zcu) },
181455 .{},
181456 );
181457 for (elements, 0..) |elem, elem_i_usize| {
181458 const elem_i: u32 = @intCast(elem_i_usize);
185441181459 if ((try result_ty.structFieldValueComptime(pt, elem_i)) != null) continue;
185442181460
185443181461 const elem_ty = result_ty.fieldType(elem_i, zcu);
185444 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
181462 const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu));
181463 if (elem_bit_size > 64) {
181464 return self.fail(
181465 "TODO airAggregateInit implement packed structs with large fields",
181466 .{},
181467 );
181468 }
181469 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu));
181470 const elem_abi_bits = elem_abi_size * 8;
181471 const elem_off = zcu.structPackedFieldBitOffset(loaded_struct, elem_i);
181472 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
181473 const elem_bit_off = elem_off % elem_abi_bits;
185445181474 const elem_mcv = try self.resolveInst(elem);
185446 try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv, .{});
185447 }
185448 break :result .{ .load_frame = .{ .index = frame_index } };
185449 },
185450 .array, .vector => {
185451 const elem_ty = result_ty.childType(zcu);
185452 if (result_ty.isVector(zcu) and elem_ty.toIntern() == .bool_type) {
185453 const result_size: u32 = @intCast(result_ty.abiSize(zcu));
185454 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
185455 try self.asmRegisterRegister(
185456 .{ ._, .xor },
185457 registerAlias(dst_reg, @min(result_size, 4)),
185458 registerAlias(dst_reg, @min(result_size, 4)),
185459 );
181475 const elem_lock = switch (elem_mcv) {
181476 .register => |reg| self.register_manager.lockReg(reg),
181477 .immediate => |imm| lock: {
181478 if (imm == 0) continue;
181479 break :lock null;
181480 },
181481 else => null,
181482 };
181483 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
185460181484
185461 for (elements, 0..) |elem, elem_i| {
185462 const elem_reg = try self.copyToTmpRegister(elem_ty, .{ .air_ref = elem });
185463 const elem_lock = self.register_manager.lockRegAssumeUnused(elem_reg);
185464 defer self.register_manager.unlockReg(elem_lock);
181485 const elem_extra_bits = self.regExtraBits(elem_ty);
181486 {
181487 const temp_reg = try self.copyToTmpRegister(elem_ty, elem_mcv);
181488 const temp_alias = registerAlias(temp_reg, elem_abi_size);
181489 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
181490 defer self.register_manager.unlockReg(temp_lock);
185465181491
185466 try self.asmRegisterImmediate(
185467 .{ ._, .@"and" },
185468 registerAlias(elem_reg, @min(result_size, 4)),
185469 .u(1),
185470 );
185471 if (elem_i > 0) try self.asmRegisterImmediate(
181492 if (elem_bit_off < elem_extra_bits) {
181493 try self.truncateRegister(elem_ty, temp_alias);
181494 }
181495 if (elem_bit_off > 0) try self.genShiftBinOpMir(
185472181496 .{ ._l, .sh },
185473 registerAlias(elem_reg, result_size),
185474 .u(@intCast(elem_i)),
181497 elem_ty,
181498 .{ .register = temp_alias },
181499 .u8,
181500 .{ .immediate = elem_bit_off },
185475181501 );
185476 try self.asmRegisterRegister(
181502 try self.genBinOpMir(
185477181503 .{ ._, .@"or" },
185478 registerAlias(dst_reg, result_size),
185479 registerAlias(elem_reg, result_size),
181504 elem_ty,
181505 .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
181506 .{ .register = temp_alias },
185480181507 );
185481181508 }
185482 break :result .{ .register = dst_reg };
185483 } else {
185484 const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu));
185485 const elem_size: u32 = @intCast(elem_ty.abiSize(zcu));
185486
185487 for (elements, 0..) |elem, elem_i| {
185488 const elem_mcv = try self.resolveInst(elem);
185489 const elem_off: i32 = @intCast(elem_size * elem_i);
185490 try self.genSetMem(
185491 .{ .frame = frame_index },
185492 elem_off,
181509 if (elem_bit_off > elem_extra_bits) {
181510 const temp_reg = try self.copyToTmpRegister(elem_ty, elem_mcv);
181511 const temp_alias = registerAlias(temp_reg, elem_abi_size);
181512 const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
181513 defer self.register_manager.unlockReg(temp_lock);
181514
181515 if (elem_extra_bits > 0) {
181516 try self.truncateRegister(elem_ty, temp_alias);
181517 }
181518 try self.genShiftBinOpMir(
181519 .{ ._r, .sh },
185493181520 elem_ty,
185494 elem_mcv,
185495 .{},
181521 .{ .register = temp_reg },
181522 .u8,
181523 .{ .immediate = elem_abi_bits - elem_bit_off },
181524 );
181525 try self.genBinOpMir(
181526 .{ ._, .@"or" },
181527 elem_ty,
181528 .{ .load_frame = .{
181529 .index = frame_index,
181530 .off = elem_byte_off + @as(i32, @intCast(elem_abi_size)),
181531 } },
181532 .{ .register = temp_alias },
185496181533 );
185497181534 }
185498 if (result_ty.sentinel(zcu)) |sentinel| try self.genSetMem(
185499 .{ .frame = frame_index },
185500 @intCast(elem_size * elements.len),
185501 elem_ty,
185502 try self.lowerValue(sentinel),
185503 .{},
181535 }
181536 break :result .{ .load_frame = .{ .index = frame_index } };
181537 },
181538 .vector => {
181539 const elem_ty = result_ty.childType(zcu);
181540 if (elem_ty.toIntern() != .bool_type) return self.fail(
181541 "TODO implement airAggregateInit for {f}",
181542 .{result_ty.fmt(pt)},
181543 );
181544 const result_size: u32 = @intCast(result_ty.abiSize(zcu));
181545 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
181546 try self.asmRegisterRegister(
181547 .{ ._, .xor },
181548 registerAlias(dst_reg, @min(result_size, 4)),
181549 registerAlias(dst_reg, @min(result_size, 4)),
181550 );
181551
181552 for (elements, 0..) |elem, elem_i| {
181553 const elem_reg = try self.copyToTmpRegister(elem_ty, .{ .air_ref = elem });
181554 const elem_lock = self.register_manager.lockRegAssumeUnused(elem_reg);
181555 defer self.register_manager.unlockReg(elem_lock);
181556
181557 try self.asmRegisterImmediate(
181558 .{ ._, .@"and" },
181559 registerAlias(elem_reg, @min(result_size, 4)),
181560 .u(1),
181561 );
181562 if (elem_i > 0) try self.asmRegisterImmediate(
181563 .{ ._l, .sh },
181564 registerAlias(elem_reg, result_size),
181565 .u(@intCast(elem_i)),
181566 );
181567 try self.asmRegisterRegister(
181568 .{ ._, .@"or" },
181569 registerAlias(dst_reg, result_size),
181570 registerAlias(elem_reg, result_size),
185504181571 );
185505 break :result .{ .load_frame = .{ .index = frame_index } };
185506181572 }
181573 break :result .{ .register = dst_reg };
185507181574 },
185508181575 else => unreachable,
185509181576 }
......@@ -185519,220 +181586,6 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {
185519181586 return self.finishAirResult(inst, result);
185520181587}
185521181588
185522fn airUnionInit(self: *CodeGen, inst: Air.Inst.Index) !void {
185523 const pt = self.pt;
185524 const zcu = pt.zcu;
185525 const ip = &zcu.intern_pool;
185526 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
185527 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
185528 const result: MCValue = result: {
185529 const union_ty = self.typeOfIndex(inst);
185530 const layout = union_ty.unionGetLayout(zcu);
185531
185532 const src_ty = self.typeOf(extra.init);
185533 const src_mcv = try self.resolveInst(extra.init);
185534 if (layout.tag_size == 0) {
185535 if (layout.abi_size <= src_ty.abiSize(zcu) and
185536 self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
185537
185538 const dst_mcv = try self.allocRegOrMem(inst, true);
185539 try self.genCopy(src_ty, dst_mcv, src_mcv, .{});
185540 break :result dst_mcv;
185541 }
185542
185543 const dst_mcv = try self.allocRegOrMem(inst, false);
185544
185545 const loaded_union = zcu.typeToUnion(union_ty).?;
185546 const field_name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];
185547 const tag_ty: Type = .fromInterned(loaded_union.enum_tag_ty);
185548 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
185549 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
185550 const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
185551 const tag_int = tag_int_val.toUnsignedInt(zcu);
185552 const tag_off: i32 = @intCast(layout.tagOffset());
185553 try self.genCopy(
185554 tag_ty,
185555 dst_mcv.address().offset(tag_off).deref(),
185556 .{ .immediate = tag_int },
185557 .{},
185558 );
185559
185560 const pl_off: i32 = @intCast(layout.payloadOffset());
185561 try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv, .{});
185562
185563 break :result dst_mcv;
185564 };
185565 return self.finishAir(inst, result, .{ extra.init, .none, .none });
185566}
185567
185568fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {
185569 const pt = self.pt;
185570 const zcu = pt.zcu;
185571 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
185572 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
185573 const ty = self.typeOfIndex(inst);
185574
185575 const ops = [3]Air.Inst.Ref{ extra.lhs, extra.rhs, pl_op.operand };
185576 const result = result: {
185577 if (switch (ty.scalarType(zcu).floatBits(self.target)) {
185578 16, 80, 128 => true,
185579 32, 64 => !self.hasFeature(.fma),
185580 else => unreachable,
185581 }) {
185582 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement airMulAdd for {f}", .{
185583 ty.fmt(pt),
185584 });
185585
185586 var sym_buf: ["__fma?".len]u8 = undefined;
185587 break :result try self.genCall(.{ .extern_func = .{
185588 .return_type = ty.toIntern(),
185589 .param_types = &.{ ty.toIntern(), ty.toIntern(), ty.toIntern() },
185590 .sym = std.fmt.bufPrint(&sym_buf, "{s}fma{s}", .{
185591 floatLibcAbiPrefix(ty),
185592 floatLibcAbiSuffix(ty),
185593 }) catch unreachable,
185594 } }, &.{ ty, ty, ty }, &.{
185595 .{ .air_ref = extra.lhs }, .{ .air_ref = extra.rhs }, .{ .air_ref = pl_op.operand },
185596 }, .{});
185597 }
185598
185599 var mcvs: [3]MCValue = undefined;
185600 var locks: [3]?RegisterManager.RegisterLock = @splat(null);
185601 defer for (locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);
185602 var order: [3]u2 = @splat(0);
185603 var unused: std.StaticBitSet(3) = .initFull();
185604 for (ops, &mcvs, &locks, 0..) |op, *mcv, *lock, op_i| {
185605 const op_index: u2 = @intCast(op_i);
185606 mcv.* = try self.resolveInst(op);
185607 if (unused.isSet(0) and mcv.isRegister() and self.reuseOperand(inst, op, op_index, mcv.*)) {
185608 order[op_index] = 1;
185609 unused.unset(0);
185610 } else if (unused.isSet(2) and mcv.isBase()) {
185611 order[op_index] = 3;
185612 unused.unset(2);
185613 }
185614 switch (mcv.*) {
185615 .register => |reg| lock.* = self.register_manager.lockReg(reg),
185616 else => {},
185617 }
185618 }
185619 for (&order, &mcvs, &locks) |*mop_index, *mcv, *lock| {
185620 if (mop_index.* != 0) continue;
185621 mop_index.* = 1 + @as(u2, @intCast(unused.toggleFirstSet().?));
185622 if (mop_index.* > 1 and mcv.isRegister()) continue;
185623 const reg = try self.copyToTmpRegister(ty, mcv.*);
185624 mcv.* = .{ .register = reg };
185625 if (lock.*) |old_lock| self.register_manager.unlockReg(old_lock);
185626 lock.* = self.register_manager.lockRegAssumeUnused(reg);
185627 }
185628
185629 const mir_tag = @as(?Mir.Inst.FixedTag, if (std.mem.eql(u2, &order, &.{ 1, 3, 2 }) or
185630 std.mem.eql(u2, &order, &.{ 3, 1, 2 }))
185631 switch (ty.zigTypeTag(zcu)) {
185632 .float => switch (ty.floatBits(self.target)) {
185633 32 => .{ .v_ss, .fmadd132 },
185634 64 => .{ .v_sd, .fmadd132 },
185635 16, 80, 128 => null,
185636 else => unreachable,
185637 },
185638 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
185639 .float => switch (ty.childType(zcu).floatBits(self.target)) {
185640 32 => switch (ty.vectorLen(zcu)) {
185641 1 => .{ .v_ss, .fmadd132 },
185642 2...8 => .{ .v_ps, .fmadd132 },
185643 else => null,
185644 },
185645 64 => switch (ty.vectorLen(zcu)) {
185646 1 => .{ .v_sd, .fmadd132 },
185647 2...4 => .{ .v_pd, .fmadd132 },
185648 else => null,
185649 },
185650 16, 80, 128 => null,
185651 else => unreachable,
185652 },
185653 else => unreachable,
185654 },
185655 else => unreachable,
185656 }
185657 else if (std.mem.eql(u2, &order, &.{ 2, 1, 3 }) or std.mem.eql(u2, &order, &.{ 1, 2, 3 }))
185658 switch (ty.zigTypeTag(zcu)) {
185659 .float => switch (ty.floatBits(self.target)) {
185660 32 => .{ .v_ss, .fmadd213 },
185661 64 => .{ .v_sd, .fmadd213 },
185662 16, 80, 128 => null,
185663 else => unreachable,
185664 },
185665 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
185666 .float => switch (ty.childType(zcu).floatBits(self.target)) {
185667 32 => switch (ty.vectorLen(zcu)) {
185668 1 => .{ .v_ss, .fmadd213 },
185669 2...8 => .{ .v_ps, .fmadd213 },
185670 else => null,
185671 },
185672 64 => switch (ty.vectorLen(zcu)) {
185673 1 => .{ .v_sd, .fmadd213 },
185674 2...4 => .{ .v_pd, .fmadd213 },
185675 else => null,
185676 },
185677 16, 80, 128 => null,
185678 else => unreachable,
185679 },
185680 else => unreachable,
185681 },
185682 else => unreachable,
185683 }
185684 else if (std.mem.eql(u2, &order, &.{ 2, 3, 1 }) or std.mem.eql(u2, &order, &.{ 3, 2, 1 }))
185685 switch (ty.zigTypeTag(zcu)) {
185686 .float => switch (ty.floatBits(self.target)) {
185687 32 => .{ .v_ss, .fmadd231 },
185688 64 => .{ .v_sd, .fmadd231 },
185689 16, 80, 128 => null,
185690 else => unreachable,
185691 },
185692 .vector => switch (ty.childType(zcu).zigTypeTag(zcu)) {
185693 .float => switch (ty.childType(zcu).floatBits(self.target)) {
185694 32 => switch (ty.vectorLen(zcu)) {
185695 1 => .{ .v_ss, .fmadd231 },
185696 2...8 => .{ .v_ps, .fmadd231 },
185697 else => null,
185698 },
185699 64 => switch (ty.vectorLen(zcu)) {
185700 1 => .{ .v_sd, .fmadd231 },
185701 2...4 => .{ .v_pd, .fmadd231 },
185702 else => null,
185703 },
185704 16, 80, 128 => null,
185705 else => unreachable,
185706 },
185707 else => unreachable,
185708 },
185709 else => unreachable,
185710 }
185711 else
185712 unreachable) orelse return self.fail("TODO implement airMulAdd for {f}", .{ty.fmt(pt)});
185713
185714 var mops: [3]MCValue = undefined;
185715 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;
185716
185717 const abi_size: u32 = @intCast(ty.abiSize(zcu));
185718 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
185719 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
185720 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
185721 mir_tag,
185722 mop1_reg,
185723 mop2_reg,
185724 registerAlias(mops[2].getReg().?, abi_size),
185725 ) else try self.asmRegisterRegisterMemory(
185726 mir_tag,
185727 mop1_reg,
185728 mop2_reg,
185729 try mops[2].mem(self, .{ .size = .fromSize(abi_size) }),
185730 );
185731 break :result mops[0];
185732 };
185733 return self.finishAir(inst, result, ops);
185734}
185735
185736181589fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void {
185737181590 const pt = self.pt;
185738181591 const zcu = pt.zcu;
......@@ -186004,27 +181857,6 @@ fn getResolvedInstValue(self: *CodeGen, inst: Air.Inst.Index) *InstTracking {
186004181857 };
186005181858}
186006181859
186007/// If the MCValue is an immediate, and it does not fit within this type,
186008/// we put it in a register.
186009/// A potential opportunity for future optimization here would be keeping track
186010/// of the fact that the instruction is available both as an immediate
186011/// and as a register.
186012fn limitImmediateType(self: *CodeGen, operand: Air.Inst.Ref, comptime T: type) !MCValue {
186013 const mcv = try self.resolveInst(operand);
186014 const ti = @typeInfo(T).int;
186015 switch (mcv) {
186016 .immediate => |imm| {
186017 // This immediate is unsigned.
186018 const U = std.meta.Int(.unsigned, ti.bits - @intFromBool(ti.signedness == .signed));
186019 if (imm >= std.math.maxInt(U)) {
186020 return MCValue{ .register = try self.copyToTmpRegister(.usize, mcv) };
186021 }
186022 },
186023 else => {},
186024 }
186025 return mcv;
186026}
186027
186028181860fn lowerValue(cg: *CodeGen, val: Value) Allocator.Error!MCValue {
186029181861 return switch (try codegen.lowerValue(cg.pt, val, cg.target)) {
186030181862 .none => .none,
......@@ -186134,7 +181966,7 @@ fn resolveCallingConventionValues(
186134181966
186135181967 const classes = switch (cc) {
186136181968 .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, cg.target, .ret), .none),
186137 .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu, cg.target)},
181969 .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu, cg.target, .ret)},
186138181970 else => unreachable,
186139181971 };
186140181972 for (classes) |class| switch (class) {
......@@ -186215,7 +182047,7 @@ fn resolveCallingConventionValues(
186215182047
186216182048 const classes = switch (cc) {
186217182049 .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ty, zcu, cg.target, .arg), .none),
186218 .x86_64_win => &.{abi.classifyWindows(ty, zcu, cg.target)},
182050 .x86_64_win => &.{abi.classifyWindows(ty, zcu, cg.target, .arg)},
186219182051 else => unreachable,
186220182052 };
186221182053 classes: for (classes) |class| switch (class) {
......@@ -186678,53 +182510,6 @@ fn typeOfIndex(self: *CodeGen, inst: Air.Inst.Index) Type {
186678182510 return Temp.typeOf(.{ .index = inst }, self);
186679182511}
186680182512
186681fn intCompilerRtAbiName(int_bits: u32) u8 {
186682 return switch (int_bits) {
186683 1...32 => 's',
186684 33...64 => 'd',
186685 65...128 => 't',
186686 else => unreachable,
186687 };
186688}
186689
186690fn floatCompilerRtAbiName(float_bits: u32) u8 {
186691 return switch (float_bits) {
186692 16 => 'h',
186693 32 => 's',
186694 64 => 'd',
186695 80 => 'x',
186696 128 => 't',
186697 else => unreachable,
186698 };
186699}
186700
186701fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type {
186702 if (ty.toIntern() == .f16_type and
186703 (other_ty.toIntern() == .f32_type or other_ty.toIntern() == .f64_type) and
186704 self.target.os.tag.isDarwin()) return .u16;
186705 return ty;
186706}
186707
186708fn floatLibcAbiPrefix(ty: Type) []const u8 {
186709 return switch (ty.toIntern()) {
186710 .f16_type, .f80_type => "__",
186711 .f32_type, .f64_type, .f128_type, .c_longdouble_type => "",
186712 else => unreachable,
186713 };
186714}
186715
186716fn floatLibcAbiSuffix(ty: Type) []const u8 {
186717 return switch (ty.toIntern()) {
186718 .f16_type => "h",
186719 .f32_type => "f",
186720 .f64_type => "",
186721 .f80_type => "x",
186722 .f128_type => "q",
186723 .c_longdouble_type => "l",
186724 else => unreachable,
186725 };
186726}
186727
186728182513fn promoteInt(self: *CodeGen, ty: Type) Type {
186729182514 const pt = self.pt;
186730182515 const zcu = pt.zcu;
src/codegen/x86_64/abi.zig+5-4
......@@ -110,7 +110,9 @@ pub const Class = enum {
110110 }
111111};
112112
113pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class {
113pub const Context = enum { ret, arg, other };
114
115pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) Class {
114116 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
115117 // "There's a strict one-to-one correspondence between a function call's arguments
116118 // and the registers used for those arguments. Any argument that doesn't fit in 8
......@@ -148,8 +150,9 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class {
148150 },
149151
150152 .float => switch (ty.floatBits(target)) {
151 16, 32, 64, 128 => .sse,
153 16, 32, 64 => .sse,
152154 80 => .memory,
155 128 => if (ctx == .arg) .memory else .sse,
153156 else => unreachable,
154157 },
155158 .vector => .sse,
......@@ -166,8 +169,6 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class {
166169 };
167170}
168171
169pub const Context = enum { ret, arg, other };
170
171172/// There are a maximum of 8 possible return slots. Returned values are in
172173/// the beginning of the array; unused slots are filled with .none.
173174pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class {
test/behavior/x86_64/binary.zig+1-10
......@@ -5172,15 +5172,6 @@ test mulSaturate {
51725172 try test_mul_saturate.testIntVectors();
51735173}
51745174
5175inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) Type {
5176 return lhs * rhs;
5177}
5178test multiply {
5179 const test_multiply = binary(multiply, .{});
5180 try test_multiply.testFloats();
5181 try test_multiply.testFloatVectors();
5182}
5183
51845175inline fn divide(comptime Type: type, lhs: Type, rhs: Type) Type {
51855176 return lhs / rhs;
51865177}
......@@ -5264,7 +5255,7 @@ inline fn mod(comptime Type: type, lhs: Type, rhs: Type) Type {
52645255 return @mod(lhs, rhs);
52655256}
52665257test mod {
5267 if (@import("builtin").object_format == .coff) return error.SkipZigTest;
5258 if (@import("builtin").object_format == .coff and @import("builtin").target.abi != .gnu) return error.SkipZigTest;
52685259 const test_mod = binary(mod, .{});
52695260 try test_mod.testInts();
52705261 try test_mod.testIntVectors();