authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-05 01:10:52-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-16 20:47:30-05:00
log3240adfa16cd09d6664223975776c80990cb55cc
treeea332760f355fcba5f84870c7ebf885d04da3b2d
parent0d9079f46654e39763bbd66090c85cdc466cc18c

x86_64: implement pointer addition and subtraction


2 files changed, 412 insertions(+), 60 deletions(-)

src/arch/x86_64/CodeGen.zig+404-58
......@@ -2404,8 +2404,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24042404 .max,
24052405 => |air_tag| try cg.airBinOp(inst, air_tag),
24062406
2407 .ptr_add, .ptr_sub => |air_tag| try cg.airPtrArithmetic(inst, air_tag),
2408
24092407 .shr, .shr_exact => try cg.airShlShrBinOp(inst),
24102408 .shl, .shl_exact => try cg.airShlShrBinOp(inst),
24112409
......@@ -2524,14 +2522,262 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
25242522 => return cg.fail("TODO implement optimized float mode", .{}),
25252523
25262524 .arg => try cg.airDbgArg(inst),
2525 .ptr_add => |air_tag| if (use_old) try cg.airPtrArithmetic(inst, air_tag) else {
2526 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
2527 const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data;
2528 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
2529 try ops[0].toSlicePtr(cg);
2530 var res: [1]Temp = undefined;
2531 cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{
2532 .patterns = &.{
2533 .{ .src = .{ .to_gpr, .simm32 } },
2534 },
2535 .dst_temps = .{.{ .rc = .general_purpose }},
2536 .each = .{ .once = &.{
2537 .{ ._, ._, .lea, .dst0p, .leaa(.none, .src0, .add_src0_elem_size_times_src1), ._, ._ },
2538 } },
2539 }, .{
2540 .dst_constraints = .{.{ .elem_size_is = 1 }},
2541 .patterns = &.{
2542 .{ .src = .{ .to_gpr, .to_gpr } },
2543 },
2544 .dst_temps = .{.{ .rc = .general_purpose }},
2545 .each = .{ .once = &.{
2546 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .src1), ._, ._ },
2547 } },
2548 }, .{
2549 .dst_constraints = .{.{ .elem_size_is = 2 }},
2550 .patterns = &.{
2551 .{ .src = .{ .to_gpr, .to_gpr } },
2552 },
2553 .dst_temps = .{.{ .rc = .general_purpose }},
2554 .each = .{ .once = &.{
2555 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"2", .src1), ._, ._ },
2556 } },
2557 }, .{
2558 .dst_constraints = .{.{ .elem_size_is = 2 + 1 }},
2559 .patterns = &.{
2560 .{ .src = .{ .to_gpr, .to_gpr } },
2561 },
2562 .dst_temps = .{.{ .rc = .general_purpose }},
2563 .each = .{ .once = &.{
2564 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"2", .src1), ._, ._ },
2565 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2566 } },
2567 }, .{
2568 .dst_constraints = .{.{ .elem_size_is = 4 }},
2569 .patterns = &.{
2570 .{ .src = .{ .to_gpr, .to_gpr } },
2571 },
2572 .dst_temps = .{.{ .rc = .general_purpose }},
2573 .each = .{ .once = &.{
2574 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"4", .src1), ._, ._ },
2575 } },
2576 }, .{
2577 .dst_constraints = .{.{ .elem_size_is = 4 + 1 }},
2578 .patterns = &.{
2579 .{ .src = .{ .to_gpr, .to_gpr } },
2580 },
2581 .dst_temps = .{.{ .ref = .src1 }},
2582 .each = .{ .once = &.{
2583 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"4", .src1), ._, ._ },
2584 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2585 } },
2586 }, .{
2587 .required_features = .{ .@"64bit", null, null, null },
2588 .dst_constraints = .{.{ .elem_size_is = 8 }},
2589 .patterns = &.{
2590 .{ .src = .{ .to_gpr, .to_gpr } },
2591 },
2592 .dst_temps = .{.{ .rc = .general_purpose }},
2593 .each = .{ .once = &.{
2594 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"8", .src1), ._, ._ },
2595 } },
2596 }, .{
2597 .required_features = .{ .@"64bit", null, null, null },
2598 .dst_constraints = .{.{ .elem_size_is = 8 + 1 }},
2599 .patterns = &.{
2600 .{ .src = .{ .to_gpr, .to_gpr } },
2601 },
2602 .dst_temps = .{.{ .ref = .src1 }},
2603 .each = .{ .once = &.{
2604 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"8", .src1), ._, ._ },
2605 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2606 } },
2607 }, .{
2608 .dst_constraints = .{.po2_elem_size},
2609 .patterns = &.{
2610 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2611 },
2612 .dst_temps = .{.{ .ref = .src1 }},
2613 .clobbers = .{ .eflags = true },
2614 .each = .{ .once = &.{
2615 .{ ._, ._l, .sh, .src1p, .sa(.none, .add_log2_src0_elem_size), ._, ._ },
2616 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .src1), ._, ._ },
2617 } },
2618 }, .{
2619 .patterns = &.{
2620 .{ .src = .{ .to_gpr, .to_gpr } },
2621 },
2622 .dst_temps = .{.{ .rc = .general_purpose }},
2623 .clobbers = .{ .eflags = true },
2624 .each = .{ .once = &.{
2625 .{ ._, .i_, .mul, .dst0p, .src1p, .sa(.none, .add_src0_elem_size), ._ },
2626 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2627 } },
2628 } }) catch |err| switch (err) {
2629 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
2630 @tagName(air_tag),
2631 cg.typeOf(bin_op.lhs).fmt(pt),
2632 ops[0].tracking(cg),
2633 ops[1].tracking(cg),
2634 }),
2635 else => |e| return e,
2636 };
2637 for (ops) |op| for (res) |r| {
2638 if (op.index == r.index) break;
2639 } else try op.die(cg);
2640 try res[0].moveTo(inst, cg);
2641 },
2642 .ptr_sub => |air_tag| if (use_old) try cg.airPtrArithmetic(inst, air_tag) else {
2643 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
2644 const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data;
2645 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
2646 try ops[0].toSlicePtr(cg);
2647 var res: [1]Temp = undefined;
2648 cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{
2649 .patterns = &.{
2650 .{ .src = .{ .to_gpr, .simm32 } },
2651 },
2652 .dst_temps = .{.{ .rc = .general_purpose }},
2653 .each = .{ .once = &.{
2654 .{ ._, ._, .lea, .dst0p, .leaa(.none, .src0, .sub_src0_elem_size_times_src1), ._, ._ },
2655 } },
2656 }, .{
2657 .dst_constraints = .{.{ .elem_size_is = 1 }},
2658 .patterns = &.{
2659 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2660 },
2661 .dst_temps = .{.{ .ref = .src1 }},
2662 .clobbers = .{ .eflags = true },
2663 .each = .{ .once = &.{
2664 .{ ._, ._, .neg, .src1p, ._, ._, ._ },
2665 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .src1), ._, ._ },
2666 } },
2667 }, .{
2668 .dst_constraints = .{.{ .elem_size_is = 2 }},
2669 .patterns = &.{
2670 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2671 },
2672 .dst_temps = .{.{ .ref = .src1 }},
2673 .clobbers = .{ .eflags = true },
2674 .each = .{ .once = &.{
2675 .{ ._, ._, .neg, .src1p, ._, ._, ._ },
2676 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"2", .src1), ._, ._ },
2677 } },
2678 }, .{
2679 .dst_constraints = .{.{ .elem_size_is = 2 + 1 }},
2680 .patterns = &.{
2681 .{ .src = .{ .to_gpr, .to_gpr } },
2682 },
2683 .dst_temps = .{.{ .rc = .general_purpose }},
2684 .clobbers = .{ .eflags = true },
2685 .each = .{ .once = &.{
2686 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"2", .src1), ._, ._ },
2687 .{ ._, ._, .neg, .dst0p, ._, ._, ._ },
2688 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2689 } },
2690 }, .{
2691 .dst_constraints = .{.{ .elem_size_is = 4 }},
2692 .patterns = &.{
2693 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2694 },
2695 .dst_temps = .{.{ .ref = .src1 }},
2696 .clobbers = .{ .eflags = true },
2697 .each = .{ .once = &.{
2698 .{ ._, ._, .neg, .src1p, ._, ._, ._ },
2699 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"4", .src1), ._, ._ },
2700 } },
2701 }, .{
2702 .dst_constraints = .{.{ .elem_size_is = 4 + 1 }},
2703 .patterns = &.{
2704 .{ .src = .{ .to_gpr, .to_gpr } },
2705 },
2706 .dst_temps = .{.{ .rc = .general_purpose }},
2707 .clobbers = .{ .eflags = true },
2708 .each = .{ .once = &.{
2709 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"4", .src1), ._, ._ },
2710 .{ ._, ._, .neg, .dst0p, ._, ._, ._ },
2711 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2712 } },
2713 }, .{
2714 .required_features = .{ .@"64bit", null, null, null },
2715 .dst_constraints = .{.{ .elem_size_is = 8 }},
2716 .patterns = &.{
2717 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2718 },
2719 .dst_temps = .{.{ .ref = .src1 }},
2720 .clobbers = .{ .eflags = true },
2721 .each = .{ .once = &.{
2722 .{ ._, ._, .neg, .src1p, ._, ._, ._ },
2723 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src0, .@"8", .src1), ._, ._ },
2724 } },
2725 }, .{
2726 .required_features = .{ .@"64bit", null, null, null },
2727 .dst_constraints = .{.{ .elem_size_is = 8 + 1 }},
2728 .patterns = &.{
2729 .{ .src = .{ .to_gpr, .to_gpr } },
2730 },
2731 .dst_temps = .{.{ .rc = .general_purpose }},
2732 .clobbers = .{ .eflags = true },
2733 .each = .{ .once = &.{
2734 .{ ._, ._, .lea, .dst0p, .leasi(.none, .src1, .@"8", .src1), ._, ._ },
2735 .{ ._, ._, .neg, .dst0p, ._, ._, ._ },
2736 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2737 } },
2738 }, .{
2739 .dst_constraints = .{.po2_elem_size},
2740 .patterns = &.{
2741 .{ .src = .{ .to_gpr, .to_mut_gpr } },
2742 },
2743 .dst_temps = .{.{ .ref = .src1 }},
2744 .clobbers = .{ .eflags = true },
2745 .each = .{ .once = &.{
2746 .{ ._, ._l, .sa, .src1p, .sa(.none, .add_log2_src0_elem_size), ._, ._ },
2747 .{ ._, ._, .neg, .src1p, ._, ._, ._ },
2748 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .src1), ._, ._ },
2749 } },
2750 }, .{
2751 .patterns = &.{
2752 .{ .src = .{ .to_gpr, .to_gpr } },
2753 },
2754 .dst_temps = .{.{ .rc = .general_purpose }},
2755 .clobbers = .{ .eflags = true },
2756 .each = .{ .once = &.{
2757 .{ ._, .i_, .mul, .dst0p, .src1p, .sa(.none, .sub_src0_elem_size), ._ },
2758 .{ ._, ._, .lea, .dst0p, .leai(.none, .src0, .dst0), ._, ._ },
2759 } },
2760 } }) catch |err| switch (err) {
2761 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
2762 @tagName(air_tag),
2763 cg.typeOf(bin_op.lhs).fmt(pt),
2764 ops[0].tracking(cg),
2765 ops[1].tracking(cg),
2766 }),
2767 else => |e| return e,
2768 };
2769 for (ops) |op| for (res) |r| {
2770 if (op.index == r.index) break;
2771 } else try op.die(cg);
2772 try res[0].moveTo(inst, cg);
2773 },
25272774 .alloc => if (use_old) try cg.airAlloc(inst) else {
25282775 var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .lea_frame = .{
25292776 .index = try cg.allocMemPtr(inst),
25302777 } });
25312778 try slot.moveTo(inst, cg);
25322779 },
2533 .inferred_alloc => unreachable,
2534 .inferred_alloc_comptime => unreachable,
2780 .inferred_alloc, .inferred_alloc_comptime => unreachable,
25352781 .ret_ptr => if (use_old) try cg.airRetPtr(inst) else {
25362782 var slot = switch (cg.ret_mcv.long) {
25372783 else => unreachable,
......@@ -2901,8 +3147,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
29013147 }),
29023148 else => |e| return e,
29033149 };
2904 if (ops[0].index != res[0].index) try ops[0].die(cg);
2905 if (ops[1].index != res[0].index) try ops[1].die(cg);
3150 for (ops) |op| for (res) |r| {
3151 if (op.index == r.index) break;
3152 } else try op.die(cg);
29063153 try res[0].moveTo(inst, cg);
29073154 },
29083155 .not => |air_tag| if (use_old) try cg.airUnOp(inst, air_tag) else {
......@@ -3953,7 +4200,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39534200 }),
39544201 else => |e| return e,
39554202 };
3956 if (ops[0].index != res[0].index) try ops[0].die(cg);
4203 for (ops) |op| for (res) |r| {
4204 if (op.index == r.index) break;
4205 } else try op.die(cg);
39574206 try res[0].moveTo(inst, cg);
39584207 },
39594208
......@@ -5016,6 +5265,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
50165265 .unused,
50175266 },
50185267 .dst_temps = .{.{ .rc = .general_purpose }},
5268 .clobbers = .{ .eflags = true },
50195269 .each = .{ .once = &.{
50205270 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
50215271 .{ .@"0:", ._, .xor, .dst0d, .dst0d, ._, ._ },
......@@ -5042,6 +5292,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
50425292 .unused,
50435293 },
50445294 .dst_temps = .{.{ .rc = .general_purpose }},
5295 .clobbers = .{ .eflags = true },
50455296 .each = .{ .once = &.{
50465297 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
50475298 .{ .@"0:", ._, .lzcnt, .dst0q, .memi(.src0q, .tmp0), ._, ._ },
......@@ -5067,6 +5318,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
50675318 .unused,
50685319 },
50695320 .dst_temps = .{.{ .rc = .general_purpose }},
5321 .clobbers = .{ .eflags = true },
50705322 .each = .{ .once = &.{
50715323 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
50725324 .{ .@"0:", ._, .xor, .dst0d, .dst0d, ._, ._ },
......@@ -5094,6 +5346,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
50945346 .unused,
50955347 },
50965348 .dst_temps = .{.{ .rc = .general_purpose }},
5349 .clobbers = .{ .eflags = true },
50975350 .each = .{ .once = &.{
50985351 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
50995352 .{ .@"0:", ._, .mov, .dst0d, .si(-1), ._, ._ },
......@@ -5120,6 +5373,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51205373 .unused,
51215374 },
51225375 .dst_temps = .{.{ .rc = .general_purpose }},
5376 .clobbers = .{ .eflags = true },
51235377 .each = .{ .once = &.{
51245378 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
51255379 .{ .@"0:", ._, .xor, .dst0d, .dst0d, ._, ._ },
......@@ -5146,6 +5400,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51465400 .unused,
51475401 },
51485402 .dst_temps = .{.{ .rc = .general_purpose }},
5403 .clobbers = .{ .eflags = true },
51495404 .each = .{ .once = &.{
51505405 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
51515406 .{ .@"0:", ._, .lzcnt, .dst0q, .memi(.src0q, .tmp0), ._, ._ },
......@@ -5171,6 +5426,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51715426 .unused,
51725427 },
51735428 .dst_temps = .{.{ .rc = .general_purpose }},
5429 .clobbers = .{ .eflags = true },
51745430 .each = .{ .once = &.{
51755431 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
51765432 .{ .@"0:", ._, .xor, .dst0d, .dst0d, ._, ._ },
......@@ -5198,6 +5454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
51985454 .unused,
51995455 },
52005456 .dst_temps = .{.{ .rc = .general_purpose }},
5457 .clobbers = .{ .eflags = true },
52015458 .each = .{ .once = &.{
52025459 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
52035460 .{ .@"0:", ._, .mov, .dst0d, .si(-1), ._, ._ },
......@@ -5224,6 +5481,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52245481 .unused,
52255482 },
52265483 .dst_temps = .{.{ .rc = .general_purpose }},
5484 .clobbers = .{ .eflags = true },
52275485 .each = .{ .once = &.{
52285486 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
52295487 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5253,6 +5511,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52535511 .unused,
52545512 },
52555513 .dst_temps = .{.{ .rc = .general_purpose }},
5514 .clobbers = .{ .eflags = true },
52565515 .each = .{ .once = &.{
52575516 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
52585517 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5281,6 +5540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52815540 .unused,
52825541 },
52835542 .dst_temps = .{.{ .rc = .general_purpose }},
5543 .clobbers = .{ .eflags = true },
52845544 .each = .{ .once = &.{
52855545 .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_size), ._, ._ },
52865546 .{ ._, ._, .mov, .dst0q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5309,6 +5569,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
53095569 .unused,
53105570 },
53115571 .dst_temps = .{.{ .rc = .general_purpose }},
5572 .clobbers = .{ .eflags = true },
53125573 .each = .{ .once = &.{
53135574 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
53145575 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5338,6 +5599,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
53385599 .unused,
53395600 },
53405601 .dst_temps = .{.{ .rc = .general_purpose }},
5602 .clobbers = .{ .eflags = true },
53415603 .each = .{ .once = &.{
53425604 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
53435605 .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5366,6 +5628,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
53665628 .unused,
53675629 },
53685630 .dst_temps = .{.{ .rc = .general_purpose }},
5631 .clobbers = .{ .eflags = true },
53695632 .each = .{ .once = &.{
53705633 .{ ._, ._, .mov, .tmp0d, .sia(-8, .src0, .add_size), ._, ._ },
53715634 .{ ._, ._, .mov, .dst0q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5394,6 +5657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
53945657 .unused,
53955658 },
53965659 .dst_temps = .{.mem},
5660 .clobbers = .{ .eflags = true },
53975661 .each = .{ .once = &.{
53985662 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
53995663 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5419,6 +5683,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
54195683 .unused,
54205684 },
54215685 .dst_temps = .{.mem},
5686 .clobbers = .{ .eflags = true },
54225687 .each = .{ .once = &.{
54235688 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
54245689 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5444,6 +5709,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
54445709 .unused,
54455710 },
54465711 .dst_temps = .{.mem},
5712 .clobbers = .{ .eflags = true },
54475713 .each = .{ .once = &.{
54485714 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
54495715 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5469,6 +5735,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
54695735 .unused,
54705736 },
54715737 .dst_temps = .{.mem},
5738 .clobbers = .{ .eflags = true },
54725739 .each = .{ .once = &.{
54735740 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
54745741 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5494,6 +5761,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
54945761 .unused,
54955762 },
54965763 .dst_temps = .{.mem},
5764 .clobbers = .{ .eflags = true },
54975765 .each = .{ .once = &.{
54985766 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
54995767 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -5519,6 +5787,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
55195787 .unused,
55205788 },
55215789 .dst_temps = .{.mem},
5790 .clobbers = .{ .eflags = true },
55225791 .each = .{ .once = &.{
55235792 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
55245793 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -5544,6 +5813,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
55445813 .unused,
55455814 },
55465815 .dst_temps = .{.mem},
5816 .clobbers = .{ .eflags = true },
55475817 .each = .{ .once = &.{
55485818 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
55495819 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5569,6 +5839,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
55695839 .unused,
55705840 },
55715841 .dst_temps = .{.mem},
5842 .clobbers = .{ .eflags = true },
55725843 .each = .{ .once = &.{
55735844 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
55745845 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -5594,6 +5865,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
55945865 .unused,
55955866 },
55965867 .dst_temps = .{.mem},
5868 .clobbers = .{ .eflags = true },
55975869 .each = .{ .once = &.{
55985870 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
55995871 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5622,6 +5894,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
56225894 .unused,
56235895 },
56245896 .dst_temps = .{.mem},
5897 .clobbers = .{ .eflags = true },
56255898 .each = .{ .once = &.{
56265899 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
56275900 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5650,6 +5923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
56505923 .unused,
56515924 },
56525925 .dst_temps = .{.mem},
5926 .clobbers = .{ .eflags = true },
56535927 .each = .{ .once = &.{
56545928 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
56555929 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5678,6 +5952,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
56785952 .unused,
56795953 },
56805954 .dst_temps = .{.mem},
5955 .clobbers = .{ .eflags = true },
56815956 .each = .{ .once = &.{
56825957 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
56835958 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5706,6 +5981,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57065981 .unused,
57075982 },
57085983 .dst_temps = .{.mem},
5984 .clobbers = .{ .eflags = true },
57095985 .each = .{ .once = &.{
57105986 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
57115987 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5732,6 +6008,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57326008 .unused,
57336009 },
57346010 .dst_temps = .{.mem},
6011 .clobbers = .{ .eflags = true },
57356012 .each = .{ .once = &.{
57366013 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
57376014 .{ .@"0:", ._, .movzx, .tmp1d, .memia(.src0b, .tmp0, .add_len), ._, ._ },
......@@ -5759,6 +6036,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57596036 .unused,
57606037 },
57616038 .dst_temps = .{.mem},
6039 .clobbers = .{ .eflags = true },
57626040 .each = .{ .once = &.{
57636041 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
57646042 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5787,6 +6065,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57876065 .unused,
57886066 },
57896067 .dst_temps = .{.mem},
6068 .clobbers = .{ .eflags = true },
57906069 .each = .{ .once = &.{
57916070 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
57926071 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5815,6 +6094,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
58156094 .unused,
58166095 },
58176096 .dst_temps = .{.mem},
6097 .clobbers = .{ .eflags = true },
58186098 .each = .{ .once = &.{
58196099 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
58206100 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5843,6 +6123,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
58436123 .unused,
58446124 },
58456125 .dst_temps = .{.mem},
6126 .clobbers = .{ .eflags = true },
58466127 .each = .{ .once = &.{
58476128 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
58486129 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5871,6 +6152,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
58716152 .unused,
58726153 },
58736154 .dst_temps = .{.mem},
6155 .clobbers = .{ .eflags = true },
58746156 .each = .{ .once = &.{
58756157 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
58766158 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5897,6 +6179,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
58976179 .unused,
58986180 },
58996181 .dst_temps = .{.mem},
6182 .clobbers = .{ .eflags = true },
59006183 .each = .{ .once = &.{
59016184 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
59026185 .{ .@"0:", ._, .movzx, .tmp1d, .memsia(.src0w, .@"2", .tmp0, .add_2_len), ._, ._ },
......@@ -5924,6 +6207,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
59246207 .unused,
59256208 },
59266209 .dst_temps = .{.mem},
6210 .clobbers = .{ .eflags = true },
59276211 .each = .{ .once = &.{
59286212 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
59296213 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5952,6 +6236,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
59526236 .unused,
59536237 },
59546238 .dst_temps = .{.mem},
6239 .clobbers = .{ .eflags = true },
59556240 .each = .{ .once = &.{
59566241 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
59576242 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -5980,6 +6265,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
59806265 .unused,
59816266 },
59826267 .dst_temps = .{.mem},
6268 .clobbers = .{ .eflags = true },
59836269 .each = .{ .once = &.{
59846270 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
59856271 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -6008,6 +6294,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60086294 .unused,
60096295 },
60106296 .dst_temps = .{.mem},
6297 .clobbers = .{ .eflags = true },
60116298 .each = .{ .once = &.{
60126299 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
60136300 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -6036,6 +6323,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60366323 .unused,
60376324 },
60386325 .dst_temps = .{.mem},
6326 .clobbers = .{ .eflags = true },
60396327 .each = .{ .once = &.{
60406328 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
60416329 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -6062,6 +6350,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60626350 .unused,
60636351 },
60646352 .dst_temps = .{.mem},
6353 .clobbers = .{ .eflags = true },
60656354 .each = .{ .once = &.{
60666355 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
60676356 .{ .@"0:", ._, .mov, .tmp1d, .memsia(.src0d, .@"4", .tmp0, .add_4_len), ._, ._ },
......@@ -6089,6 +6378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60896378 .unused,
60906379 },
60916380 .dst_temps = .{.mem},
6381 .clobbers = .{ .eflags = true },
60926382 .each = .{ .once = &.{
60936383 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
60946384 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -6117,6 +6407,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61176407 .unused,
61186408 },
61196409 .dst_temps = .{.mem},
6410 .clobbers = .{ .eflags = true },
61206411 .each = .{ .once = &.{
61216412 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
61226413 .{ ._, ._, .mov, .tmp1d, .si(0xff), ._, ._ },
......@@ -6145,6 +6436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61456436 .unused,
61466437 },
61476438 .dst_temps = .{.mem},
6439 .clobbers = .{ .eflags = true },
61486440 .each = .{ .once = &.{
61496441 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
61506442 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -6173,6 +6465,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61736465 .unused,
61746466 },
61756467 .dst_temps = .{.mem},
6468 .clobbers = .{ .eflags = true },
61766469 .each = .{ .once = &.{
61776470 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
61786471 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -6201,6 +6494,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62016494 .unused,
62026495 },
62036496 .dst_temps = .{.mem},
6497 .clobbers = .{ .eflags = true },
62046498 .each = .{ .once = &.{
62056499 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
62066500 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -6228,6 +6522,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62286522 .unused,
62296523 },
62306524 .dst_temps = .{.mem},
6525 .clobbers = .{ .eflags = true },
62316526 .each = .{ .once = &.{
62326527 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
62336528 .{ .@"0:", ._, .mov, .tmp1q, .ua(.src0, .add_umax), ._, ._ },
......@@ -6256,6 +6551,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62566551 .unused,
62576552 },
62586553 .dst_temps = .{.mem},
6554 .clobbers = .{ .eflags = true },
62596555 .each = .{ .once = &.{
62606556 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
62616557 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6292,6 +6588,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62926588 .unused,
62936589 },
62946590 .dst_temps = .{.mem},
6591 .clobbers = .{ .eflags = true },
62956592 .each = .{ .once = &.{
62966593 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
62976594 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6327,6 +6624,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
63276624 .unused,
63286625 },
63296626 .dst_temps = .{.mem},
6627 .clobbers = .{ .eflags = true },
63306628 .each = .{ .once = &.{
63316629 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
63326630 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6362,6 +6660,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
63626660 .unused,
63636661 },
63646662 .dst_temps = .{.mem},
6663 .clobbers = .{ .eflags = true },
63656664 .each = .{ .once = &.{
63666665 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
63676666 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6398,6 +6697,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
63986697 .unused,
63996698 },
64006699 .dst_temps = .{.mem},
6700 .clobbers = .{ .eflags = true },
64016701 .each = .{ .once = &.{
64026702 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
64036703 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6433,6 +6733,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
64336733 .unused,
64346734 },
64356735 .dst_temps = .{.mem},
6736 .clobbers = .{ .eflags = true },
64366737 .each = .{ .once = &.{
64376738 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
64386739 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6468,6 +6769,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
64686769 .unused,
64696770 },
64706771 .dst_temps = .{.mem},
6772 .clobbers = .{ .eflags = true },
64716773 .each = .{ .once = &.{
64726774 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
64736775 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6504,6 +6806,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
65046806 .unused,
65056807 },
65066808 .dst_temps = .{.mem},
6809 .clobbers = .{ .eflags = true },
65076810 .each = .{ .once = &.{
65086811 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
65096812 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6539,6 +6842,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
65396842 .unused,
65406843 },
65416844 .dst_temps = .{.mem},
6845 .clobbers = .{ .eflags = true },
65426846 .each = .{ .once = &.{
65436847 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
65446848 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6574,6 +6878,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
65746878 .unused,
65756879 },
65766880 .dst_temps = .{.mem},
6881 .clobbers = .{ .eflags = true },
65776882 .each = .{ .once = &.{
65786883 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
65796884 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6610,6 +6915,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
66106915 .unused,
66116916 },
66126917 .dst_temps = .{.mem},
6918 .clobbers = .{ .eflags = true },
66136919 .each = .{ .once = &.{
66146920 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
66156921 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6645,6 +6951,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
66456951 .unused,
66466952 },
66476953 .dst_temps = .{.mem},
6954 .clobbers = .{ .eflags = true },
66486955 .each = .{ .once = &.{
66496956 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_len), ._, ._ },
66506957 .{ ._, ._, .lea, .tmp1q, .mem(.src0), ._, ._ },
......@@ -6672,7 +6979,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
66726979 }),
66736980 else => |e| return e,
66746981 };
6675 if (ops[0].index != res[0].index) try ops[0].die(cg);
6982 for (ops) |op| for (res) |r| {
6983 if (op.index == r.index) break;
6984 } else try op.die(cg);
66766985 try res[0].moveTo(inst, cg);
66776986 },
66786987
......@@ -8480,8 +8789,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
84808789 .gte => unreachable,
84818790 .gt => unreachable,
84828791 }
8483 if (ops[0].index != res[0].index) try ops[0].die(cg);
8484 if (ops[1].index != res[0].index) try ops[1].die(cg);
8792 for (ops) |op| for (res) |r| {
8793 if (op.index == r.index) break;
8794 } else try op.die(cg);
84858795 try res[0].moveTo(inst, cg);
84868796 },
84878797
......@@ -8678,8 +8988,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
86788988 }),
86798989 else => |e| return e,
86808990 };
8681 if (ops[0].index != res[0].index) try ops[0].die(cg);
8682 if (ops[1].index != res[0].index) try ops[1].die(cg);
8991 for (ops) |op| for (res) |r| {
8992 if (op.index == r.index) break;
8993 } else try op.die(cg);
86838994 try res[0].moveTo(inst, cg);
86848995 },
86858996 .cmp_eq,
......@@ -9155,8 +9466,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
91559466 }),
91569467 else => |e| return e,
91579468 };
9158 if (ops[0].index != res[0].index) try ops[0].die(cg);
9159 if (ops[1].index != res[0].index) try ops[1].die(cg);
9469 for (ops) |op| for (res) |r| {
9470 if (op.index == r.index) break;
9471 } else try op.die(cg);
91609472 try res[0].moveTo(inst, cg);
91619473 },
91629474
......@@ -9294,7 +9606,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
92949606 .int_from_ptr => if (use_old) try cg.airIntFromPtr(inst) else {
92959607 const un_op = air_datas[@intFromEnum(inst)].un_op;
92969608 var ops = try cg.tempsFromOperands(inst, .{un_op});
9297 try ops[0].toLimb(0, cg);
9609 try ops[0].toSlicePtr(cg);
92989610 try ops[0].moveTo(inst, cg);
92999611 },
93009612 .int_from_bool => if (use_old) try cg.airIntFromBool(inst) else {
......@@ -9422,13 +9734,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
94229734 .slice_len => if (use_old) try cg.airSliceLen(inst) else {
94239735 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
94249736 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
9425 try ops[0].toLimb(1, cg);
9737 try ops[0].toSliceLen(cg);
94269738 try ops[0].moveTo(inst, cg);
94279739 },
94289740 .slice_ptr => if (use_old) try cg.airSlicePtr(inst) else {
94299741 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
94309742 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
9431 try ops[0].toLimb(0, cg);
9743 try ops[0].toSlicePtr(cg);
94329744 try ops[0].moveTo(inst, cg);
94339745 },
94349746 .ptr_slice_len_ptr => if (use_old) try cg.airPtrSliceLenPtr(inst) else {
......@@ -9450,17 +9762,21 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
94509762 } else {
94519763 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
94529764 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
9453 switch (air_tag) {
9454 else => unreachable,
9455 .slice_elem_val => try ops[0].toLimb(0, cg),
9456 .ptr_elem_val => {},
9457 }
9765 try ops[0].toSlicePtr(cg);
94589766 var res: [1]Temp = undefined;
94599767 const res_ty = cg.typeOfIndex(inst);
94609768 cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
94619769 .dst_constraints = .{.{ .int = .byte }},
94629770 .patterns = &.{
94639771 .{ .src = .{ .to_gpr, .simm32 } },
9772 },
9773 .dst_temps = .{.{ .rc = .general_purpose }},
9774 .each = .{ .once = &.{
9775 .{ ._, ._, .movzx, .dst0d, .leaa(.byte, .src0, .add_src0_elem_size_times_src1), ._, ._ },
9776 } },
9777 }, .{
9778 .dst_constraints = .{.{ .int = .byte }},
9779 .patterns = &.{
94649780 .{ .src = .{ .to_gpr, .to_gpr } },
94659781 },
94669782 .dst_temps = .{.{ .rc = .general_purpose }},
......@@ -9471,6 +9787,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
94719787 .dst_constraints = .{.{ .int = .word }},
94729788 .patterns = &.{
94739789 .{ .src = .{ .to_gpr, .simm32 } },
9790 },
9791 .dst_temps = .{.{ .rc = .general_purpose }},
9792 .each = .{ .once = &.{
9793 .{ ._, ._, .movzx, .dst0d, .leaa(.word, .src0, .add_src0_elem_size_times_src1), ._, ._ },
9794 } },
9795 }, .{
9796 .dst_constraints = .{.{ .int = .word }},
9797 .patterns = &.{
94749798 .{ .src = .{ .to_gpr, .to_gpr } },
94759799 },
94769800 .dst_temps = .{.{ .rc = .general_purpose }},
......@@ -9481,6 +9805,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
94819805 .dst_constraints = .{.{ .int = .dword }},
94829806 .patterns = &.{
94839807 .{ .src = .{ .to_gpr, .simm32 } },
9808 },
9809 .dst_temps = .{.{ .rc = .general_purpose }},
9810 .each = .{ .once = &.{
9811 .{ ._, ._, .mov, .dst0d, .leaa(.dword, .src0, .add_src0_elem_size_times_src1), ._, ._ },
9812 } },
9813 }, .{
9814 .dst_constraints = .{.{ .int = .dword }},
9815 .patterns = &.{
94849816 .{ .src = .{ .to_gpr, .to_gpr } },
94859817 },
94869818 .dst_temps = .{.{ .rc = .general_purpose }},
......@@ -9488,10 +9820,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
94889820 .{ ._, ._, .mov, .dst0d, .leasi(.dword, .src0, .@"4", .src1), ._, ._ },
94899821 } },
94909822 }, .{
9491 .required_features = .{ .@"64bit", null, null, null },
94929823 .dst_constraints = .{.{ .int = .qword }},
94939824 .patterns = &.{
94949825 .{ .src = .{ .to_gpr, .simm32 } },
9826 },
9827 .dst_temps = .{.{ .rc = .general_purpose }},
9828 .each = .{ .once = &.{
9829 .{ ._, ._, .mov, .dst0q, .leaa(.qword, .src0, .add_src0_elem_size_times_src1), ._, ._ },
9830 } },
9831 }, .{
9832 .required_features = .{ .@"64bit", null, null, null },
9833 .dst_constraints = .{.{ .int = .qword }},
9834 .patterns = &.{
94959835 .{ .src = .{ .to_gpr, .to_gpr } },
94969836 },
94979837 .dst_temps = .{.{ .rc = .general_purpose }},
......@@ -9543,8 +9883,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
95439883 },
95449884 else => |e| return e,
95459885 };
9546 if (ops[0].index != res[0].index) try ops[0].die(cg);
9547 if (ops[1].index != res[0].index) try ops[1].die(cg);
9886 for (ops) |op| for (res) |r| {
9887 if (op.index == r.index) break;
9888 } else try op.die(cg);
95489889 try res[0].moveTo(inst, cg);
95499890 },
95509891 .slice_elem_ptr, .ptr_elem_ptr => |air_tag| if (use_old) switch (air_tag) {
......@@ -9555,11 +9896,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
95559896 const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
95569897 const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data;
95579898 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
9558 switch (air_tag) {
9559 else => unreachable,
9560 .slice_elem_ptr => try ops[0].toLimb(0, cg),
9561 .ptr_elem_ptr => {},
9562 }
9899 try ops[0].toSlicePtr(cg);
95639900 const dst_ty = cg.typeOfIndex(inst);
95649901 if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: {
95659902 const elem_size = dst_ty.childType(zcu).abiSize(zcu);
......@@ -27687,9 +28024,9 @@ const Temp = struct {
2768728024 temp.* = new_temp;
2768828025 }
2768928026
27690 fn getLimb(temp: Temp, limb_index: u28, cg: *CodeGen) !Temp {
28027 fn getLimb(temp: Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !Temp {
2769128028 const new_temp_index = cg.next_temp_index;
27692 cg.temp_type[@intFromEnum(new_temp_index)] = .usize;
28029 cg.temp_type[@intFromEnum(new_temp_index)] = limb_ty;
2769328030 switch (temp.tracking(cg).short) {
2769428031 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
2769528032 .immediate => |imm| {
......@@ -27759,7 +28096,7 @@ const Temp = struct {
2775928096 return .{ .index = new_temp_index.toIndex() };
2776028097 }
2776128098
27762 fn toLimb(temp: *Temp, limb_index: u28, cg: *CodeGen) !void {
28099 fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !void {
2776328100 switch (temp.unwrap(cg)) {
2776428101 .ref => {},
2776528102 .temp => |temp_index| {
......@@ -27768,7 +28105,7 @@ const Temp = struct {
2776828105 else => {},
2776928106 .register, .lea_symbol, .lea_frame => {
2777028107 assert(limb_index == 0);
27771 cg.temp_type[@intFromEnum(temp_index)] = .usize;
28108 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
2777228109 return;
2777328110 },
2777428111 .register_pair => |regs| {
......@@ -27780,7 +28117,7 @@ const Temp = struct {
2778028117 for (regs, 0..) |reg, reg_index| if (reg_index != limb_index)
2778128118 cg.register_manager.freeReg(reg);
2778228119 temp_tracking.* = .init(.{ .register = regs[limb_index] });
27783 cg.temp_type[@intFromEnum(temp_index)] = .usize;
28120 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
2778428121 return;
2778528122 },
2778628123 .load_symbol => |sym_off| {
......@@ -27789,7 +28126,7 @@ const Temp = struct {
2778928126 .sym_index = sym_off.sym_index,
2779028127 .off = sym_off.off + @as(u31, limb_index) * 8,
2779128128 } });
27792 cg.temp_type[@intFromEnum(temp_index)] = .usize;
28129 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
2779328130 return;
2779428131 },
2779528132 .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) {
......@@ -27798,17 +28135,26 @@ const Temp = struct {
2779828135 .index = frame_addr.index,
2779928136 .off = frame_addr.off + @as(u31, limb_index) * 8,
2780028137 } });
27801 cg.temp_type[@intFromEnum(temp_index)] = .usize;
28138 cg.temp_type[@intFromEnum(temp_index)] = limb_ty;
2780228139 return;
2780328140 },
2780428141 }
2780528142 },
2780628143 }
27807 const new_temp = try temp.getLimb(limb_index, cg);
28144 const new_temp = try temp.getLimb(limb_ty, limb_index, cg);
2780828145 try temp.die(cg);
2780928146 temp.* = new_temp;
2781028147 }
2781128148
28149 fn toSlicePtr(temp: *Temp, cg: *CodeGen) !void {
28150 const temp_ty = temp.typeOf(cg);
28151 if (temp_ty.isSlice(cg.pt.zcu)) try temp.toLimb(temp_ty.slicePtrFieldType(cg.pt.zcu), 0, cg);
28152 }
28153
28154 fn toSliceLen(temp: *Temp, cg: *CodeGen) !void {
28155 try temp.toLimb(.usize, 1, cg);
28156 }
28157
2781228158 fn toReg(temp: *Temp, new_reg: Register, cg: *CodeGen) !bool {
2781328159 const val, const ty = val_ty: switch (temp.unwrap(cg)) {
2781428160 .ref => |ref| .{ temp.tracking(cg).short, cg.typeOf(ref) },
......@@ -28325,6 +28671,8 @@ const Select = struct {
2832528671 unsigned_or_exact_remainder_int: struct { of: Memory.Size, is: Memory.Size },
2832628672 signed_int: Memory.Size,
2832728673 unsigned_int: Memory.Size,
28674 elem_size_is: u8,
28675 po2_elem_size,
2832828676 elem_int: Memory.Size,
2832928677
2833028678 fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool {
......@@ -28511,8 +28859,10 @@ const Select = struct {
2851128859 const int_info = ty.intInfo(zcu);
2851228860 return int_info.signedness == .unsigned and size.bitSize(cg.target) >= int_info.bits;
2851328861 },
28862 .elem_size_is => |size| return size == ty.elemType2(zcu).abiSize(zcu),
28863 .po2_elem_size => return std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)),
2851428864 .elem_int => |size| {
28515 const elem_ty = ty.childType(zcu);
28865 const elem_ty = ty.elemType2(zcu);
2851628866 if (elem_ty.toIntern() == .bool_type) return true;
2851728867 if (elem_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();
2851828868 return elem_ty.isAbiInt(zcu) and size.bitSize(cg.target) >= elem_ty.intInfo(zcu).bits;
......@@ -28794,6 +29144,8 @@ const Select = struct {
2879429144 len,
2879529145 elem_limbs,
2879629146 src0_elem_size,
29147 src0_elem_size_times_src1,
29148 log2_src0_elem_size,
2879729149 smin,
2879829150 smax,
2879929151 umax,
......@@ -28818,7 +29170,13 @@ const Select = struct {
2881829170 const add_len: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .len };
2881929171 const sub_len: Adjust = .{ .factor = -1, .scale = .@"1", .amount = .len };
2882029172 const add_src0_elem_size: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .src0_elem_size };
29173 const add_2_src0_elem_size: Adjust = .{ .factor = 1, .scale = .@"2", .amount = .src0_elem_size };
29174 const add_4_src0_elem_size: Adjust = .{ .factor = 1, .scale = .@"4", .amount = .src0_elem_size };
29175 const add_8_src0_elem_size: Adjust = .{ .factor = 1, .scale = .@"8", .amount = .src0_elem_size };
2882129176 const sub_src0_elem_size: Adjust = .{ .factor = -1, .scale = .@"1", .amount = .src0_elem_size };
29177 const add_src0_elem_size_times_src1: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .src0_elem_size_times_src1 };
29178 const sub_src0_elem_size_times_src1: Adjust = .{ .factor = -1, .scale = .@"1", .amount = .src0_elem_size_times_src1 };
29179 const add_log2_src0_elem_size: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .log2_src0_elem_size };
2882229180 const add_elem_limbs: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .elem_limbs };
2882329181 const add_umax: Adjust = .{ .factor = 1, .scale = .@"1", .amount = .umax };
2882429182 };
......@@ -29190,14 +29548,7 @@ const Select = struct {
2919029548 const UnsignedImm = @Type(.{
2919129549 .int = .{ .signedness = .unsigned, .bits = @typeInfo(SignedImm).int.bits },
2919229550 });
29193 return switch (op.index.ref) {
29194 else => |ref| switch (ref.deref(s).tracking(s.cg).short) {
29195 else => unreachable,
29196 .immediate => |imm| op.index.scale.toFactor() * @as(i32, @intCast(imm)),
29197 .register => 0,
29198 },
29199 .none => 0,
29200 } + @as(i5, op.adjust.factor) * op.adjust.scale.toFactor() * @as(SignedImm, switch (op.adjust.amount) {
29551 return @as(i5, op.adjust.factor) * op.adjust.scale.toFactor() * @as(SignedImm, switch (op.adjust.amount) {
2920129552 .none => 0,
2920229553 .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8),
2920329554 .ptr_bit_size => s.cg.target.ptrBitWidth(),
......@@ -29210,7 +29561,10 @@ const Select = struct {
2921029561 op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu),
2921129562 @divExact(op.base.size.bitSize(s.cg.target), 8),
2921229563 )),
29213 .src0_elem_size => @intCast(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).childType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
29564 .src0_elem_size => @intCast(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
29565 .src0_elem_size_times_src1 => @intCast(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu) *
29566 Select.Operand.Ref.src1.deref(s).tracking(s.cg).short.immediate),
29567 .log2_src0_elem_size => @intCast(std.math.log2(Select.Operand.Ref.src0.deref(s).typeOf(s.cg).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))),
2921429568 .smin => @as(SignedImm, std.math.minInt(SignedImm)) >> @truncate(
2921529569 -%op.base.ref.deref(s).typeOf(s.cg).scalarType(s.cg.pt.zcu).bitSize(s.cg.pt.zcu),
2921629570 ),
......@@ -29250,11 +29604,7 @@ const Select = struct {
2925029604 .mod = .{ .rm = .{
2925129605 .size = op.base.size,
2925229606 .index = switch (op.index.ref) {
29253 else => |ref| switch (ref.deref(s).tracking(s.cg).short) {
29254 else => unreachable,
29255 .immediate => .none,
29256 .register => |index_reg| registerAlias(index_reg, @divExact(s.cg.target.ptrBitWidth(), 8)),
29257 },
29607 else => |ref| registerAlias(ref.deref(s).tracking(s.cg).short.register, @divExact(s.cg.target.ptrBitWidth(), 8)),
2925829608 .none => .none,
2925929609 },
2926029610 .scale = op.index.scale,
......@@ -29264,11 +29614,7 @@ const Select = struct {
2926429614 .mem => .{ .mem = try op.base.ref.deref(s).tracking(s.cg).short.mem(s.cg, .{
2926529615 .size = op.base.size,
2926629616 .index = switch (op.index.ref) {
29267 else => |ref| switch (ref.deref(s).tracking(s.cg).short) {
29268 else => unreachable,
29269 .immediate => .none,
29270 .register => |index_reg| registerAlias(index_reg, @divExact(s.cg.target.ptrBitWidth(), 8)),
29271 },
29617 else => |ref| registerAlias(ref.deref(s).tracking(s.cg).short.register, @divExact(s.cg.target.ptrBitWidth(), 8)),
2927229618 .none => .none,
2927329619 },
2927429620 .scale = op.index.scale,
test/behavior/x86_64/mem.zig+8-2
......@@ -4,13 +4,19 @@ fn access(comptime array: anytype) !void {
44 inline for (0.., &array) |ct_index, *elem| {
55 var rt_index: usize = undefined;
66 rt_index = ct_index;
7 if (&(slice.ptr + ct_index)[0] != elem) return error.Unexpected;
8 if (&(slice.ptr + rt_index)[0] != elem) return error.Unexpected;
9 if (&slice.ptr[ct_index..][0] != elem) return error.Unexpected;
10 if (&slice.ptr[rt_index..][0] != elem) return error.Unexpected;
711 if (&slice.ptr[ct_index] != elem) return error.Unexpected;
8 if (&slice[ct_index] != elem) return error.Unexpected;
912 if (&slice.ptr[rt_index] != elem) return error.Unexpected;
13 if (&slice[ct_index..].ptr[0] != elem) return error.Unexpected;
14 if (&slice[rt_index..].ptr[0] != elem) return error.Unexpected;
15 if (&slice[ct_index] != elem) return error.Unexpected;
1016 if (&slice[rt_index] != elem) return error.Unexpected;
1117 if (slice.ptr[ct_index] != elem.*) return error.Unexpected;
12 if (slice[ct_index] != elem.*) return error.Unexpected;
1318 if (slice.ptr[rt_index] != elem.*) return error.Unexpected;
19 if (slice[ct_index] != elem.*) return error.Unexpected;
1420 if (slice[rt_index] != elem.*) return error.Unexpected;
1521 }
1622}