| ... | @@ -2467,8 +2467,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2467,8 +2467,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2467 | .memcpy => try cg.airMemcpy(inst), | 2467 | .memcpy => try cg.airMemcpy(inst), |
| 2468 | .memset => try cg.airMemset(inst, false), | 2468 | .memset => try cg.airMemset(inst, false), |
| 2469 | .memset_safe => try cg.airMemset(inst, true), | 2469 | .memset_safe => try cg.airMemset(inst, true), |
| 2470 | .set_union_tag => try cg.airSetUnionTag(inst), | | |
| 2471 | .get_union_tag => try cg.airGetUnionTag(inst), | | |
| 2472 | .ctz => try cg.airCtz(inst), | 2470 | .ctz => try cg.airCtz(inst), |
| 2473 | .popcount => try cg.airPopCount(inst), | 2471 | .popcount => try cg.airPopCount(inst), |
| 2474 | .byte_swap => try cg.airByteSwap(inst), | 2472 | .byte_swap => try cg.airByteSwap(inst), |
| ... | @@ -2480,7 +2478,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2480,7 +2478,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2480 | .shuffle => try cg.airShuffle(inst), | 2478 | .shuffle => try cg.airShuffle(inst), |
| 2481 | .reduce => try cg.airReduce(inst), | 2479 | .reduce => try cg.airReduce(inst), |
| 2482 | .aggregate_init => try cg.airAggregateInit(inst), | 2480 | .aggregate_init => try cg.airAggregateInit(inst), |
| 2483 | .union_init => try cg.airUnionInit(inst), | | |
| 2484 | .prefetch => try cg.airPrefetch(inst), | 2481 | .prefetch => try cg.airPrefetch(inst), |
| 2485 | .mul_add => try cg.airMulAdd(inst), | 2482 | .mul_add => try cg.airMulAdd(inst), |
| 2486 | | 2483 | |
| ... | @@ -2528,7 +2525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2528,7 +2525,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2528 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 2525 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 2529 | try ops[0].toSlicePtr(cg); | 2526 | try ops[0].toSlicePtr(cg); |
| 2530 | var res: [1]Temp = undefined; | 2527 | var res: [1]Temp = undefined; |
| 2531 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{ | 2528 | cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{ |
| 2532 | .patterns = &.{ | 2529 | .patterns = &.{ |
| 2533 | .{ .src = .{ .to_gpr, .simm32 } }, | 2530 | .{ .src = .{ .to_gpr, .simm32 } }, |
| 2534 | }, | 2531 | }, |
| ... | @@ -2645,7 +2642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2645,7 +2642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2645 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 2642 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 2646 | try ops[0].toSlicePtr(cg); | 2643 | try ops[0].toSlicePtr(cg); |
| 2647 | var res: [1]Temp = undefined; | 2644 | var res: [1]Temp = undefined; |
| 2648 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{ | 2645 | cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{ |
| 2649 | .patterns = &.{ | 2646 | .patterns = &.{ |
| 2650 | .{ .src = .{ .to_gpr, .simm32 } }, | 2647 | .{ .src = .{ .to_gpr, .simm32 } }, |
| 2651 | }, | 2648 | }, |
| ... | @@ -2772,20 +2769,22 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2772,20 +2769,22 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2772 | try res[0].moveTo(inst, cg); | 2769 | try res[0].moveTo(inst, cg); |
| 2773 | }, | 2770 | }, |
| 2774 | .alloc => if (use_old) try cg.airAlloc(inst) else { | 2771 | .alloc => if (use_old) try cg.airAlloc(inst) else { |
| 2775 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .lea_frame = .{ | 2772 | const ty = air_datas[@intFromEnum(inst)].ty; |
| | 2773 | var slot = try cg.tempInit(ty, .{ .lea_frame = .{ |
| 2776 | .index = try cg.allocMemPtr(inst), | 2774 | .index = try cg.allocMemPtr(inst), |
| 2777 | } }); | 2775 | } }); |
| 2778 | try slot.moveTo(inst, cg); | 2776 | try slot.moveTo(inst, cg); |
| 2779 | }, | 2777 | }, |
| 2780 | .inferred_alloc, .inferred_alloc_comptime => unreachable, | 2778 | .inferred_alloc, .inferred_alloc_comptime => unreachable, |
| 2781 | .ret_ptr => if (use_old) try cg.airRetPtr(inst) else { | 2779 | .ret_ptr => if (use_old) try cg.airRetPtr(inst) else { |
| | 2780 | const ty = air_datas[@intFromEnum(inst)].ty; |
| 2782 | var slot = switch (cg.ret_mcv.long) { | 2781 | var slot = switch (cg.ret_mcv.long) { |
| 2783 | else => unreachable, | 2782 | else => unreachable, |
| 2784 | .none => try cg.tempFromValue(cg.typeOfIndex(inst), .{ .lea_frame = .{ | 2783 | .none => try cg.tempInit(ty, .{ .lea_frame = .{ |
| 2785 | .index = try cg.allocMemPtr(inst), | 2784 | .index = try cg.allocMemPtr(inst), |
| 2786 | } }), | 2785 | } }), |
| 2787 | .load_frame => slot: { | 2786 | .load_frame => slot: { |
| 2788 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), cg.ret_mcv.long); | 2787 | var slot = try cg.tempInit(ty, cg.ret_mcv.long); |
| 2789 | try slot.toOffset(cg.ret_mcv.short.indirect.off, cg); | 2788 | try slot.toOffset(cg.ret_mcv.short.indirect.off, cg); |
| 2790 | break :slot slot; | 2789 | break :slot slot; |
| 2791 | }, | 2790 | }, |
| ... | @@ -2797,7 +2796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2797,7 +2796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2797 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; | 2796 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 2798 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 2797 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 2799 | var res: [1]Temp = undefined; | 2798 | var res: [1]Temp = undefined; |
| 2800 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, switch (@as(Mir.Inst.Tag, switch (air_tag) { | 2799 | cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, switch (@as(Mir.Inst.Tag, switch (air_tag) { |
| 2801 | else => unreachable, | 2800 | else => unreachable, |
| 2802 | .bit_and => .@"and", | 2801 | .bit_and => .@"and", |
| 2803 | .bit_or => .@"or", | 2802 | .bit_or => .@"or", |
| ... | @@ -3156,7 +3155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -3156,7 +3155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 3156 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 3155 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 3157 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 3156 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 3158 | var res: [1]Temp = undefined; | 3157 | var res: [1]Temp = undefined; |
| 3159 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{ | 3158 | cg.select(&res, &.{ty_op.ty.toType()}, &ops, comptime &.{ .{ |
| 3160 | .src_constraints = .{ .{ .signed_or_exact_int = .byte }, .any }, | 3159 | .src_constraints = .{ .{ .signed_or_exact_int = .byte }, .any }, |
| 3161 | .patterns = &.{ | 3160 | .patterns = &.{ |
| 3162 | .{ .src = .{ .mut_mem, .none } }, | 3161 | .{ .src = .{ .mut_mem, .none } }, |
| ... | @@ -4239,14 +4238,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -4239,14 +4238,14 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4239 | .trap => try cg.asmOpOnly(.{ ._, .ud2 }), | 4238 | .trap => try cg.asmOpOnly(.{ ._, .ud2 }), |
| 4240 | .breakpoint => try cg.asmOpOnly(.{ ._, .int3 }), | 4239 | .breakpoint => try cg.asmOpOnly(.{ ._, .int3 }), |
| 4241 | .ret_addr => if (use_old) try cg.airRetAddr(inst) else { | 4240 | .ret_addr => if (use_old) try cg.airRetAddr(inst) else { |
| 4242 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .load_frame = .{ | 4241 | var slot = try cg.tempInit(.usize, .{ .load_frame = .{ |
| 4243 | .index = .ret_addr, | 4242 | .index = .ret_addr, |
| 4244 | } }); | 4243 | } }); |
| 4245 | while (try slot.toRegClass(true, .general_purpose, cg)) {} | 4244 | while (try slot.toRegClass(true, .general_purpose, cg)) {} |
| 4246 | try slot.moveTo(inst, cg); | 4245 | try slot.moveTo(inst, cg); |
| 4247 | }, | 4246 | }, |
| 4248 | .frame_addr => if (use_old) try cg.airFrameAddress(inst) else { | 4247 | .frame_addr => if (use_old) try cg.airFrameAddress(inst) else { |
| 4249 | var slot = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .lea_frame = .{ | 4248 | var slot = try cg.tempInit(.usize, .{ .lea_frame = .{ |
| 4250 | .index = .base_ptr, | 4249 | .index = .base_ptr, |
| 4251 | } }); | 4250 | } }); |
| 4252 | try slot.moveTo(inst, cg); | 4251 | try slot.moveTo(inst, cg); |
| ... | @@ -4260,7 +4259,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -4260,7 +4259,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4260 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 4259 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 4261 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 4260 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 4262 | var res: [1]Temp = undefined; | 4261 | var res: [1]Temp = undefined; |
| 4263 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, comptime &.{ .{ | 4262 | cg.select(&res, &.{ty_op.ty.toType()}, &ops, comptime &.{ .{ |
| 4264 | .required_features = .{ .slow_incdec, null, null, null }, | 4263 | .required_features = .{ .slow_incdec, null, null, null }, |
| 4265 | .src_constraints = .{ .{ .exact_signed_int = 1 }, .any }, | 4264 | .src_constraints = .{ .{ .exact_signed_int = 1 }, .any }, |
| 4266 | .patterns = &.{ | 4265 | .patterns = &.{ |
| ... | @@ -6997,7 +6996,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6997,7 +6996,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6997 | switch (extra.compareOperator()) { | 6996 | switch (extra.compareOperator()) { |
| 6998 | .lt => unreachable, | 6997 | .lt => unreachable, |
| 6999 | .lte => unreachable, | 6998 | .lte => unreachable, |
| 7000 | .eq, .neq => |cmp_op| cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, switch (@as(Condition, switch (cmp_op) { | 6999 | .eq, .neq => |cmp_op| cg.select(&res, &.{ty_pl.ty.toType()}, &ops, switch (@as(Condition, switch (cmp_op) { |
| 7001 | else => unreachable, | 7000 | else => unreachable, |
| 7002 | .eq => .e, | 7001 | .eq => .e, |
| 7003 | .neq => .ne, | 7002 | .neq => .ne, |
| ... | @@ -8825,7 +8824,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -8825,7 +8824,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 8825 | .unsigned; | 8824 | .unsigned; |
| 8826 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 8825 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 8827 | var res: [1]Temp = undefined; | 8826 | var res: [1]Temp = undefined; |
| 8828 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, switch (@as(Condition, switch (signedness) { | 8827 | cg.select(&res, &.{.bool}, &ops, switch (@as(Condition, switch (signedness) { |
| 8829 | .signed => switch (air_tag) { | 8828 | .signed => switch (air_tag) { |
| 8830 | else => unreachable, | 8829 | else => unreachable, |
| 8831 | .cmp_lt, .cmp_lt_optimized => .l, | 8830 | .cmp_lt, .cmp_lt_optimized => .l, |
| ... | @@ -9011,7 +9010,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9011,7 +9010,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9011 | }); | 9010 | }); |
| 9012 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 9011 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 9013 | var res: [1]Temp = undefined; | 9012 | var res: [1]Temp = undefined; |
| 9014 | cg.select(&res, &.{cg.typeOfIndex(inst)}, &ops, switch (@as(Condition, switch (air_tag) { | 9013 | cg.select(&res, &.{.bool}, &ops, switch (@as(Condition, switch (air_tag) { |
| 9015 | else => unreachable, | 9014 | else => unreachable, |
| 9016 | .cmp_eq, .cmp_eq_optimized => .e, | 9015 | .cmp_eq, .cmp_eq_optimized => .e, |
| 9017 | .cmp_neq, .cmp_neq_optimized => .ne, | 9016 | .cmp_neq, .cmp_neq_optimized => .ne, |
| ... | @@ -9540,7 +9539,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9540,7 +9539,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9540 | .fromSize(opt_child_abi_size) }), | 9539 | .fromSize(opt_child_abi_size) }), |
| 9541 | .u(0), | 9540 | .u(0), |
| 9542 | ); | 9541 | ); |
| 9543 | var is_null = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .eflags = .e }); | 9542 | var is_null = try cg.tempInit(.bool, .{ .eflags = .e }); |
| 9544 | try ops[0].die(cg); | 9543 | try ops[0].die(cg); |
| 9545 | try is_null.moveTo(inst, cg); | 9544 | try is_null.moveTo(inst, cg); |
| 9546 | }, | 9545 | }, |
| ... | @@ -9563,7 +9562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9563,7 +9562,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9563 | .fromSize(opt_child_abi_size) }), | 9562 | .fromSize(opt_child_abi_size) }), |
| 9564 | .u(0), | 9563 | .u(0), |
| 9565 | ); | 9564 | ); |
| 9566 | var is_non_null = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .eflags = .ne }); | 9565 | var is_non_null = try cg.tempInit(.bool, .{ .eflags = .ne }); |
| 9567 | try ops[0].die(cg); | 9566 | try ops[0].die(cg); |
| 9568 | try is_non_null.moveTo(inst, cg); | 9567 | try is_non_null.moveTo(inst, cg); |
| 9569 | }, | 9568 | }, |
| ... | @@ -9581,7 +9580,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9581,7 +9580,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9581 | try ops[0].tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(eu_err_ty) }), | 9580 | try ops[0].tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(eu_err_ty) }), |
| 9582 | .u(0), | 9581 | .u(0), |
| 9583 | ); | 9582 | ); |
| 9584 | var is_err = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .eflags = .ne }); | 9583 | var is_err = try cg.tempInit(.bool, .{ .eflags = .ne }); |
| 9585 | try ops[0].die(cg); | 9584 | try ops[0].die(cg); |
| 9586 | try is_err.moveTo(inst, cg); | 9585 | try is_err.moveTo(inst, cg); |
| 9587 | }, | 9586 | }, |
| ... | @@ -9599,7 +9598,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9599,7 +9598,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9599 | try ops[0].tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(eu_err_ty) }), | 9598 | try ops[0].tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(eu_err_ty) }), |
| 9600 | .u(0), | 9599 | .u(0), |
| 9601 | ); | 9600 | ); |
| 9602 | var is_non_err = try cg.tempFromValue(cg.typeOfIndex(inst), .{ .eflags = .e }); | 9601 | var is_non_err = try cg.tempInit(.bool, .{ .eflags = .e }); |
| 9603 | try ops[0].die(cg); | 9602 | try ops[0].die(cg); |
| 9604 | try is_non_err.moveTo(inst, cg); | 9603 | try is_non_err.moveTo(inst, cg); |
| 9605 | }, | 9604 | }, |
| ... | @@ -9631,8 +9630,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9631,8 +9630,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9631 | const opt_child_ty = opt_ty.optionalChild(zcu); | 9630 | const opt_child_ty = opt_ty.optionalChild(zcu); |
| 9632 | const opt_child_abi_size: i32 = @intCast(opt_child_ty.abiSize(zcu)); | 9631 | const opt_child_abi_size: i32 = @intCast(opt_child_ty.abiSize(zcu)); |
| 9633 | try ops[0].toOffset(opt_child_abi_size, cg); | 9632 | try ops[0].toOffset(opt_child_abi_size, cg); |
| 9634 | var has_value = try cg.tempFromValue(.bool, .{ .immediate = 1 }); | 9633 | var has_value = try cg.tempInit(.bool, .{ .immediate = 1 }); |
| 9635 | try ops[0].store(&has_value, cg); | 9634 | try ops[0].store(0, &has_value, cg); |
| 9636 | try has_value.die(cg); | 9635 | try has_value.die(cg); |
| 9637 | try ops[0].toOffset(-opt_child_abi_size, cg); | 9636 | try ops[0].toOffset(-opt_child_abi_size, cg); |
| 9638 | } | 9637 | } |
| ... | @@ -9654,7 +9653,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9654,7 +9653,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9654 | const eu_err_off: i32 = @intCast(codegen.errUnionErrorOffset(eu_pl_ty, zcu)); | 9653 | const eu_err_off: i32 = @intCast(codegen.errUnionErrorOffset(eu_pl_ty, zcu)); |
| 9655 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9654 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9656 | try ops[0].toOffset(eu_err_off, cg); | 9655 | try ops[0].toOffset(eu_err_off, cg); |
| 9657 | var err = try ops[0].load(eu_ty.errorUnionSet(zcu), cg); | 9656 | var err = try ops[0].load(0, eu_ty.errorUnionSet(zcu), cg); |
| 9658 | try ops[0].die(cg); | 9657 | try ops[0].die(cg); |
| 9659 | try err.moveTo(inst, cg); | 9658 | try err.moveTo(inst, cg); |
| 9660 | }, | 9659 | }, |
| ... | @@ -9667,8 +9666,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9667,8 +9666,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9667 | const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu)); | 9666 | const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu)); |
| 9668 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9667 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9669 | try ops[0].toOffset(eu_err_off, cg); | 9668 | try ops[0].toOffset(eu_err_off, cg); |
| 9670 | var no_err = try cg.tempFromValue(eu_err_ty, .{ .immediate = 0 }); | 9669 | var no_err = try cg.tempInit(eu_err_ty, .{ .immediate = 0 }); |
| 9671 | try ops[0].store(&no_err, cg); | 9670 | try ops[0].store(0, &no_err, cg); |
| 9672 | try no_err.die(cg); | 9671 | try no_err.die(cg); |
| 9673 | try ops[0].toOffset(eu_pl_off - eu_err_off, cg); | 9672 | try ops[0].toOffset(eu_pl_off - eu_err_off, cg); |
| 9674 | try ops[0].moveTo(inst, cg); | 9673 | try ops[0].moveTo(inst, cg); |
| ... | @@ -9679,7 +9678,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9679,7 +9678,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9679 | var ops = try cg.tempsFromOperands(inst, .{extra.struct_operand}); | 9678 | var ops = try cg.tempsFromOperands(inst, .{extra.struct_operand}); |
| 9680 | try ops[0].toOffset(cg.fieldOffset( | 9679 | try ops[0].toOffset(cg.fieldOffset( |
| 9681 | cg.typeOf(extra.struct_operand), | 9680 | cg.typeOf(extra.struct_operand), |
| 9682 | cg.typeOfIndex(inst), | 9681 | ty_pl.ty.toType(), |
| 9683 | extra.field_index, | 9682 | extra.field_index, |
| 9684 | ), cg); | 9683 | ), cg); |
| 9685 | try ops[0].moveTo(inst, cg); | 9684 | try ops[0].moveTo(inst, cg); |
| ... | @@ -9689,7 +9688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9689,7 +9688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9689 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9688 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9690 | try ops[0].toOffset(cg.fieldOffset( | 9689 | try ops[0].toOffset(cg.fieldOffset( |
| 9691 | cg.typeOf(ty_op.operand), | 9690 | cg.typeOf(ty_op.operand), |
| 9692 | cg.typeOfIndex(inst), | 9691 | ty_op.ty.toType(), |
| 9693 | 0, | 9692 | 0, |
| 9694 | ), cg); | 9693 | ), cg); |
| 9695 | try ops[0].moveTo(inst, cg); | 9694 | try ops[0].moveTo(inst, cg); |
| ... | @@ -9699,7 +9698,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9699,7 +9698,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9699 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9698 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9700 | try ops[0].toOffset(cg.fieldOffset( | 9699 | try ops[0].toOffset(cg.fieldOffset( |
| 9701 | cg.typeOf(ty_op.operand), | 9700 | cg.typeOf(ty_op.operand), |
| 9702 | cg.typeOfIndex(inst), | 9701 | ty_op.ty.toType(), |
| 9703 | 1, | 9702 | 1, |
| 9704 | ), cg); | 9703 | ), cg); |
| 9705 | try ops[0].moveTo(inst, cg); | 9704 | try ops[0].moveTo(inst, cg); |
| ... | @@ -9709,7 +9708,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9709,7 +9708,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9709 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9708 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9710 | try ops[0].toOffset(cg.fieldOffset( | 9709 | try ops[0].toOffset(cg.fieldOffset( |
| 9711 | cg.typeOf(ty_op.operand), | 9710 | cg.typeOf(ty_op.operand), |
| 9712 | cg.typeOfIndex(inst), | 9711 | ty_op.ty.toType(), |
| 9713 | 2, | 9712 | 2, |
| 9714 | ), cg); | 9713 | ), cg); |
| 9715 | try ops[0].moveTo(inst, cg); | 9714 | try ops[0].moveTo(inst, cg); |
| ... | @@ -9719,11 +9718,29 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9719,11 +9718,29 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9719 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9718 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9720 | try ops[0].toOffset(cg.fieldOffset( | 9719 | try ops[0].toOffset(cg.fieldOffset( |
| 9721 | cg.typeOf(ty_op.operand), | 9720 | cg.typeOf(ty_op.operand), |
| 9722 | cg.typeOfIndex(inst), | 9721 | ty_op.ty.toType(), |
| 9723 | 3, | 9722 | 3, |
| 9724 | ), cg); | 9723 | ), cg); |
| 9725 | try ops[0].moveTo(inst, cg); | 9724 | try ops[0].moveTo(inst, cg); |
| 9726 | }, | 9725 | }, |
| | 9726 | .set_union_tag => if (use_old) try cg.airSetUnionTag(inst) else { |
| | 9727 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| | 9728 | const union_ty = cg.typeOf(bin_op.lhs).childType(zcu); |
| | 9729 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| | 9730 | const union_layout = union_ty.unionGetLayout(zcu); |
| | 9731 | if (union_layout.tag_size > 0) try ops[0].store(@intCast(union_layout.tagOffset()), &ops[1], cg); |
| | 9732 | for (ops) |op| try op.die(cg); |
| | 9733 | }, |
| | 9734 | .get_union_tag => if (use_old) try cg.airGetUnionTag(inst) else { |
| | 9735 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| | 9736 | const union_ty = cg.typeOf(ty_op.operand); |
| | 9737 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| | 9738 | const union_layout = union_ty.unionGetLayout(zcu); |
| | 9739 | assert(union_layout.tag_size > 0); |
| | 9740 | var res = try ops[0].read(@intCast(union_layout.tagOffset()), ty_op.ty.toType(), cg); |
| | 9741 | for (ops) |op| if (op.index != res.index) try op.die(cg); |
| | 9742 | try res.moveTo(inst, cg); |
| | 9743 | }, |
| 9727 | .slice => if (use_old) try cg.airSlice(inst) else { | 9744 | .slice => if (use_old) try cg.airSlice(inst) else { |
| 9728 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 9745 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 9729 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; | 9746 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -9764,7 +9781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9764,7 +9781,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9764 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 9781 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 9765 | try ops[0].toSlicePtr(cg); | 9782 | try ops[0].toSlicePtr(cg); |
| 9766 | var res: [1]Temp = undefined; | 9783 | var res: [1]Temp = undefined; |
| 9767 | const res_ty = cg.typeOfIndex(inst); | 9784 | const res_ty = cg.typeOf(bin_op.lhs).elemType2(zcu); |
| 9768 | cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{ | 9785 | cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{ |
| 9769 | .dst_constraints = .{.{ .int = .byte }}, | 9786 | .dst_constraints = .{.{ .int = .byte }}, |
| 9770 | .patterns = &.{ | 9787 | .patterns = &.{ |
| ... | @@ -9840,7 +9857,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9840,7 +9857,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9840 | } }, | 9857 | } }, |
| 9841 | } }) catch |err| switch (err) { | 9858 | } }) catch |err| switch (err) { |
| 9842 | error.SelectFailed => switch (res_ty.abiSize(zcu)) { | 9859 | error.SelectFailed => switch (res_ty.abiSize(zcu)) { |
| 9843 | 0 => res[0] = try cg.tempFromValue(res_ty, .none), | 9860 | 0 => res[0] = try cg.tempInit(res_ty, .none), |
| 9844 | else => |elem_size| { | 9861 | else => |elem_size| { |
| 9845 | while (true) for (&ops) |*op| { | 9862 | while (true) for (&ops) |*op| { |
| 9846 | if (try op.toRegClass(true, .general_purpose, cg)) break; | 9863 | if (try op.toRegClass(true, .general_purpose, cg)) break; |
| ... | @@ -9878,7 +9895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9878,7 +9895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9878 | .scale = .fromFactor(@intCast(elem_size)), | 9895 | .scale = .fromFactor(@intCast(elem_size)), |
| 9879 | } }, | 9896 | } }, |
| 9880 | }); | 9897 | }); |
| 9881 | res[0] = try ops[0].load(res_ty, cg); | 9898 | res[0] = try ops[0].load(0, res_ty, cg); |
| 9882 | }, | 9899 | }, |
| 9883 | }, | 9900 | }, |
| 9884 | else => |e| return e, | 9901 | else => |e| return e, |
| ... | @@ -9897,7 +9914,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9897,7 +9914,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9897 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; | 9914 | const bin_op = cg.air.extraData(Air.Bin, ty_pl.payload).data; |
| 9898 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 9915 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 9899 | try ops[0].toSlicePtr(cg); | 9916 | try ops[0].toSlicePtr(cg); |
| 9900 | const dst_ty = cg.typeOfIndex(inst); | 9917 | const dst_ty = ty_pl.ty.toType(); |
| 9901 | if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: { | 9918 | if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: { |
| 9902 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); | 9919 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); |
| 9903 | if (elem_size == 0) break :zero_offset; | 9920 | if (elem_size == 0) break :zero_offset; |
| ... | @@ -9944,19 +9961,38 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9944,19 +9961,38 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9944 | .array_to_slice => if (use_old) try cg.airArrayToSlice(inst) else { | 9961 | .array_to_slice => if (use_old) try cg.airArrayToSlice(inst) else { |
| 9945 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; | 9962 | const ty_op = air_datas[@intFromEnum(inst)].ty_op; |
| 9946 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); | 9963 | var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}); |
| 9947 | var len = try cg.tempFromValue(.usize, .{ | 9964 | var len = try cg.tempInit(.usize, .{ |
| 9948 | .immediate = cg.typeOf(ty_op.operand).childType(zcu).arrayLen(zcu), | 9965 | .immediate = cg.typeOf(ty_op.operand).childType(zcu).arrayLen(zcu), |
| 9949 | }); | 9966 | }); |
| 9950 | try ops[0].toPair(&len, cg); | 9967 | try ops[0].toPair(&len, cg); |
| 9951 | try ops[0].moveTo(inst, cg); | 9968 | try ops[0].moveTo(inst, cg); |
| 9952 | }, | 9969 | }, |
| 9953 | .error_set_has_value => return cg.fail("TODO implement error_set_has_value", .{}), | 9970 | .error_set_has_value => return cg.fail("TODO implement error_set_has_value", .{}), |
| | 9971 | .union_init => if (use_old) try cg.airUnionInit(inst) else { |
| | 9972 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| | 9973 | const extra = cg.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| | 9974 | const union_ty = ty_pl.ty.toType(); |
| | 9975 | var ops = try cg.tempsFromOperands(inst, .{extra.init}); |
| | 9976 | var res = try cg.tempAllocMem(union_ty); |
| | 9977 | const union_layout = union_ty.unionGetLayout(zcu); |
| | 9978 | if (union_layout.tag_size > 0) { |
| | 9979 | var tag_temp = try cg.tempFromValue(try pt.enumValueFieldIndex( |
| | 9980 | union_ty.unionTagTypeSafety(zcu).?, |
| | 9981 | extra.field_index, |
| | 9982 | )); |
| | 9983 | try res.write(@intCast(union_layout.tagOffset()), &tag_temp, cg); |
| | 9984 | try tag_temp.die(cg); |
| | 9985 | } |
| | 9986 | try res.write(@intCast(union_layout.payloadOffset()), &ops[0], cg); |
| | 9987 | try ops[0].die(cg); |
| | 9988 | try res.moveTo(inst, cg); |
| | 9989 | }, |
| 9954 | .field_parent_ptr => if (use_old) try cg.airFieldParentPtr(inst) else { | 9990 | .field_parent_ptr => if (use_old) try cg.airFieldParentPtr(inst) else { |
| 9955 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 9991 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 9956 | const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | 9992 | const extra = cg.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 9957 | var ops = try cg.tempsFromOperands(inst, .{extra.field_ptr}); | 9993 | var ops = try cg.tempsFromOperands(inst, .{extra.field_ptr}); |
| 9958 | try ops[0].toOffset(-cg.fieldOffset( | 9994 | try ops[0].toOffset(-cg.fieldOffset( |
| 9959 | cg.typeOfIndex(inst), | 9995 | ty_pl.ty.toType(), |
| 9960 | cg.typeOf(extra.field_ptr), | 9996 | cg.typeOf(extra.field_ptr), |
| 9961 | extra.field_index, | 9997 | extra.field_index, |
| 9962 | ), cg); | 9998 | ), cg); |
| ... | @@ -10273,7 +10309,7 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok | ... | @@ -10273,7 +10309,7 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok |
| 10273 | }; | 10309 | }; |
| 10274 | | 10310 | |
| 10275 | if (reg_ok) need_mem: { | 10311 | if (reg_ok) need_mem: { |
| 10276 | if (abi_size <= @as(u32, switch (ty.zigTypeTag(zcu)) { | 10312 | if (std.math.isPowerOfTwo(abi_size) and abi_size <= @as(u32, switch (ty.zigTypeTag(zcu)) { |
| 10277 | .float => switch (ty.floatBits(self.target.*)) { | 10313 | .float => switch (ty.floatBits(self.target.*)) { |
| 10278 | 16, 32, 64, 128 => 16, | 10314 | 16, 32, 64, 128 => 16, |
| 10279 | 80 => break :need_mem, | 10315 | 80 => break :need_mem, |
| ... | @@ -11042,7 +11078,8 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -11042,7 +11078,8 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 11042 | if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; | 11078 | if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; |
| 11043 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 11079 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 11044 | | 11080 | |
| 11045 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 11081 | const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.class() == self.regClassForType(dst_ty) and |
| | 11082 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 11046 | src_mcv | 11083 | src_mcv |
| 11047 | else if (dst_abi_size <= 8) | 11084 | else if (dst_abi_size <= 8) |
| 11048 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv) | 11085 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv) |
| ... | @@ -15513,12 +15550,12 @@ fn airLoad(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -15513,12 +15550,12 @@ fn airLoad(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15513 | const ptr_ty = self.typeOf(ty_op.operand); | 15550 | const ptr_ty = self.typeOf(ty_op.operand); |
| 15514 | const elem_size = elem_ty.abiSize(zcu); | 15551 | const elem_size = elem_ty.abiSize(zcu); |
| 15515 | | 15552 | |
| 15516 | const elem_rc = self.regSetForType(elem_ty); | 15553 | const elem_rs = self.regSetForType(elem_ty); |
| 15517 | const ptr_rc = self.regSetForType(ptr_ty); | 15554 | const ptr_rs = self.regSetForType(ptr_ty); |
| 15518 | | 15555 | |
| 15519 | const ptr_mcv = try self.resolveInst(ty_op.operand); | 15556 | const ptr_mcv = try self.resolveInst(ty_op.operand); |
| 15520 | const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and | 15557 | const dst_mcv = if (elem_size <= 8 and std.math.isPowerOfTwo(elem_size) and |
| 15521 | self.reuseOperand(inst, ty_op.operand, 0, ptr_mcv)) | 15558 | elem_rs.supersetOf(ptr_rs) and self.reuseOperand(inst, ty_op.operand, 0, ptr_mcv)) |
| 15522 | // The MCValue that holds the pointer can be re-used as the value. | 15559 | // The MCValue that holds the pointer can be re-used as the value. |
| 15523 | ptr_mcv | 15560 | ptr_mcv |
| 15524 | else | 15561 | else |
| ... | @@ -28295,17 +28332,19 @@ const Temp = struct { | ... | @@ -28295,17 +28332,19 @@ const Temp = struct { |
| 28295 | return true; | 28332 | return true; |
| 28296 | } | 28333 | } |
| 28297 | | 28334 | |
| 28298 | fn load(ptr: *Temp, val_ty: Type, cg: *CodeGen) !Temp { | 28335 | fn load(ptr: *Temp, disp: i32, val_ty: Type, cg: *CodeGen) !Temp { |
| 28299 | const val = try cg.tempAlloc(val_ty); | 28336 | const val = try cg.tempAlloc(val_ty); |
| 28300 | switch (val.tracking(cg).short) { | 28337 | const val_mcv = val.tracking(cg).short; |
| | 28338 | switch (val_mcv) { |
| 28301 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 28339 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 28302 | .register => |val_reg| { | 28340 | .register => |val_reg| { |
| 28303 | while (try ptr.toLea(cg)) {} | 28341 | while (try ptr.toLea(cg)) {} |
| 28304 | try cg.genSetReg(val_reg, val_ty, ptr.tracking(cg).short.deref(), .{}); | 28342 | try cg.genSetReg(val_reg, val_ty, ptr.tracking(cg).short.offset(disp).deref(), .{}); |
| 28305 | }, | 28343 | }, |
| 28306 | .load_frame => |val_frame_addr| { | 28344 | .memory, .indirect, .load_frame, .load_symbol => { |
| 28307 | var val_ptr = try cg.tempFromValue(.usize, .{ .lea_frame = val_frame_addr }); | 28345 | try ptr.toOffset(disp, cg); |
| 28308 | var len = try cg.tempFromValue(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | 28346 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| | 28347 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| 28309 | try val_ptr.memcpy(ptr, &len, cg); | 28348 | try val_ptr.memcpy(ptr, &len, cg); |
| 28310 | try val_ptr.die(cg); | 28349 | try val_ptr.die(cg); |
| 28311 | try len.die(cg); | 28350 | try len.die(cg); |
| ... | @@ -28314,27 +28353,38 @@ const Temp = struct { | ... | @@ -28314,27 +28353,38 @@ const Temp = struct { |
| 28314 | return val; | 28353 | return val; |
| 28315 | } | 28354 | } |
| 28316 | | 28355 | |
| 28317 | fn store(ptr: *Temp, val: *Temp, cg: *CodeGen) !void { | 28356 | fn store(ptr: *Temp, disp: i32, val: *Temp, cg: *CodeGen) !void { |
| 28318 | const val_ty = val.typeOf(cg); | 28357 | const val_ty = val.typeOf(cg); |
| 28319 | const val_abi_size: u32 = @intCast(val_ty.abiSize(cg.pt.zcu)); | | |
| 28320 | val: switch (val.tracking(cg).short) { | 28358 | val: switch (val.tracking(cg).short) { |
| 28321 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 28359 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 28322 | .immediate => |imm| if (std.math.cast(i32, imm)) |s| { | 28360 | .immediate => |val_imm| { |
| | 28361 | const val_op: Immediate = if (std.math.cast(u32, val_imm)) |val_uimm32| |
| | 28362 | .u(val_uimm32) |
| | 28363 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| |
| | 28364 | .s(val_simm32) |
| | 28365 | else |
| | 28366 | continue :val .{ .register = undefined }; |
| 28323 | while (try ptr.toLea(cg)) {} | 28367 | while (try ptr.toLea(cg)) {} |
| 28324 | try cg.asmMemoryImmediate( | 28368 | try cg.asmMemoryImmediate( |
| 28325 | .{ ._, .mov }, | 28369 | .{ ._, .mov }, |
| 28326 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(val_ty) }), | 28370 | try ptr.tracking(cg).short.deref().mem(cg, .{ |
| 28327 | .s(s), | 28371 | .size = cg.memSize(val_ty), |
| | 28372 | .disp = disp, |
| | 28373 | }), |
| | 28374 | val_op, |
| 28328 | ); | 28375 | ); |
| 28329 | } else continue :val .{ .register = undefined }, | 28376 | }, |
| 28330 | .register => { | 28377 | .register => { |
| 28331 | while (try ptr.toLea(cg) or try val.toRegClass(true, .general_purpose, cg)) {} | 28378 | while (try ptr.toLea(cg) or try val.toRegClass(true, .general_purpose, cg)) {} |
| 28332 | const val_reg = val.tracking(cg).short.register; | 28379 | const val_reg = val.tracking(cg).short.register; |
| 28333 | switch (val_reg.class()) { | 28380 | switch (val_reg.class()) { |
| 28334 | .general_purpose => try cg.asmMemoryRegister( | 28381 | .general_purpose => try cg.asmMemoryRegister( |
| 28335 | .{ ._, .mov }, | 28382 | .{ ._, .mov }, |
| 28336 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = cg.memSize(val_ty) }), | 28383 | try ptr.tracking(cg).short.deref().mem(cg, .{ |
| 28337 | registerAlias(val_reg, val_abi_size), | 28384 | .size = cg.memSize(val_ty), |
| | 28385 | .disp = disp, |
| | 28386 | }), |
| | 28387 | registerAlias(val_reg, @intCast(val_ty.abiSize(cg.pt.zcu))), |
| 28338 | ), | 28388 | ), |
| 28339 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 28389 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 28340 | } | 28390 | } |
| ... | @@ -28342,6 +28392,111 @@ const Temp = struct { | ... | @@ -28342,6 +28392,111 @@ const Temp = struct { |
| 28342 | } | 28392 | } |
| 28343 | } | 28393 | } |
| 28344 | | 28394 | |
| | 28395 | fn read(src: *Temp, disp: i32, val_ty: Type, cg: *CodeGen) !Temp { |
| | 28396 | const val = try cg.tempAlloc(val_ty); |
| | 28397 | while (try src.toBase(cg)) {} |
| | 28398 | const val_mcv = val.tracking(cg).short; |
| | 28399 | switch (val_mcv) { |
| | 28400 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 28401 | .register => |val_reg| try src.readReg(disp, val_ty, registerAlias( |
| | 28402 | val_reg, |
| | 28403 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 28404 | ), cg), |
| | 28405 | } |
| | 28406 | return val; |
| | 28407 | } |
| | 28408 | |
| | 28409 | fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { |
| | 28410 | const strat = try cg.moveStrategy(dst_ty, dst_reg.class(), false); |
| | 28411 | try strat.read(cg, dst_reg, try src.tracking(cg).short.mem(cg, .{ |
| | 28412 | .size = .fromBitSize(@min(8 * dst_ty.abiSize(cg.pt.zcu), dst_reg.bitSize())), |
| | 28413 | .disp = disp, |
| | 28414 | })); |
| | 28415 | } |
| | 28416 | |
| | 28417 | fn write(dst: *Temp, disp: i32, val: *Temp, cg: *CodeGen) !void { |
| | 28418 | const val_ty = val.typeOf(cg); |
| | 28419 | while (try dst.toBase(cg)) {} |
| | 28420 | val_to_gpr: while (true) : (while (try val.toRegClass(false, .general_purpose, cg)) {}) { |
| | 28421 | const val_mcv = val.tracking(cg).short; |
| | 28422 | switch (val_mcv) { |
| | 28423 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 28424 | .immediate => |val_imm| { |
| | 28425 | const val_op: Immediate = if (std.math.cast(u32, val_imm)) |val_uimm32| |
| | 28426 | .u(val_uimm32) |
| | 28427 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| |
| | 28428 | .s(val_simm32) |
| | 28429 | else |
| | 28430 | continue :val_to_gpr; |
| | 28431 | try cg.asmMemoryImmediate( |
| | 28432 | .{ ._, .mov }, |
| | 28433 | try dst.tracking(cg).short.mem(cg, .{ |
| | 28434 | .size = cg.memSize(val_ty), |
| | 28435 | .disp = disp, |
| | 28436 | }), |
| | 28437 | val_op, |
| | 28438 | ); |
| | 28439 | }, |
| | 28440 | .register => |val_reg| try dst.writeReg(disp, val_ty, registerAlias( |
| | 28441 | val_reg, |
| | 28442 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 28443 | ), cg), |
| | 28444 | inline .register_pair, .register_triple, .register_quadruple => |val_regs| { |
| | 28445 | var part_disp = disp; |
| | 28446 | for (val_regs) |val_reg| { |
| | 28447 | try dst.writeReg(part_disp, val_ty, val_reg, cg); |
| | 28448 | part_disp += @divExact(val_reg.bitSize(), 8); |
| | 28449 | } |
| | 28450 | }, |
| | 28451 | .register_offset => |val_reg_off| switch (val_reg_off.off) { |
| | 28452 | 0 => try dst.writeReg(disp, val_ty, registerAlias( |
| | 28453 | val_reg_off.reg, |
| | 28454 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 28455 | ), cg), |
| | 28456 | else => continue :val_to_gpr, |
| | 28457 | }, |
| | 28458 | .lea_frame, .lea_symbol => continue :val_to_gpr, |
| | 28459 | .memory, .indirect, .load_frame, .load_symbol => { |
| | 28460 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(disp)); |
| | 28461 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| | 28462 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| | 28463 | try dst_ptr.memcpy(&val_ptr, &len, cg); |
| | 28464 | try dst_ptr.die(cg); |
| | 28465 | try val_ptr.die(cg); |
| | 28466 | try len.die(cg); |
| | 28467 | }, |
| | 28468 | } |
| | 28469 | break; |
| | 28470 | } |
| | 28471 | } |
| | 28472 | |
| | 28473 | fn writeReg(dst: Temp, disp: i32, src_ty: Type, src_reg: Register, cg: *CodeGen) !void { |
| | 28474 | const src_rc = src_reg.class(); |
| | 28475 | const src_abi_size = src_ty.abiSize(cg.pt.zcu); |
| | 28476 | const strat = try cg.moveStrategy(src_ty, src_rc, false); |
| | 28477 | if (src_rc == .x87 or std.math.isPowerOfTwo(src_abi_size)) { |
| | 28478 | try strat.write(cg, try dst.tracking(cg).short.mem(cg, .{ |
| | 28479 | .size = .fromBitSize(@min(8 * src_abi_size, src_reg.bitSize())), |
| | 28480 | .disp = disp, |
| | 28481 | }), src_reg); |
| | 28482 | } else { |
| | 28483 | const frame_alloc: FrameAlloc = .initSpill(src_ty, cg.pt.zcu); |
| | 28484 | const frame_index = try cg.allocFrameIndex(frame_alloc); |
| | 28485 | const frame_size: Memory.Size = .fromSize(frame_alloc.abi_size); |
| | 28486 | try strat.write(cg, .{ |
| | 28487 | .base = .{ .frame = frame_index }, |
| | 28488 | .mod = .{ .rm = .{ .size = frame_size } }, |
| | 28489 | }, src_reg); |
| | 28490 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address()); |
| | 28491 | var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } }); |
| | 28492 | var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size }); |
| | 28493 | try dst_ptr.memcpy(&src_ptr, &len, cg); |
| | 28494 | try dst_ptr.die(cg); |
| | 28495 | try src_ptr.die(cg); |
| | 28496 | try len.die(cg); |
| | 28497 | } |
| | 28498 | } |
| | 28499 | |
| 28345 | fn memcpy(dst: *Temp, src: *Temp, len: *Temp, cg: *CodeGen) !void { | 28500 | fn memcpy(dst: *Temp, src: *Temp, len: *Temp, cg: *CodeGen) !void { |
| 28346 | while (true) for ([_]*Temp{ dst, src, len }, [_]Register{ .rdi, .rsi, .rcx }) |temp, reg| { | 28501 | while (true) for ([_]*Temp{ dst, src, len }, [_]Register{ .rdi, .rsi, .rcx }) |temp, reg| { |
| 28347 | if (try temp.toReg(reg, cg)) break; | 28502 | if (try temp.toReg(reg, cg)) break; |
| ... | @@ -28498,7 +28653,7 @@ fn tempAllocMem(cg: *CodeGen, ty: Type) !Temp { | ... | @@ -28498,7 +28653,7 @@ fn tempAllocMem(cg: *CodeGen, ty: Type) !Temp { |
| 28498 | return .{ .index = temp_index.toIndex() }; | 28653 | return .{ .index = temp_index.toIndex() }; |
| 28499 | } | 28654 | } |
| 28500 | | 28655 | |
| 28501 | fn tempFromValue(cg: *CodeGen, ty: Type, value: MCValue) !Temp { | 28656 | fn tempInit(cg: *CodeGen, ty: Type, value: MCValue) !Temp { |
| 28502 | const temp_index = cg.next_temp_index; | 28657 | const temp_index = cg.next_temp_index; |
| 28503 | temp_index.tracking(cg).* = .init(value); | 28658 | temp_index.tracking(cg).* = .init(value); |
| 28504 | cg.temp_type[@intFromEnum(temp_index)] = ty; | 28659 | cg.temp_type[@intFromEnum(temp_index)] = ty; |
| ... | @@ -28507,6 +28662,10 @@ fn tempFromValue(cg: *CodeGen, ty: Type, value: MCValue) !Temp { | ... | @@ -28507,6 +28662,10 @@ fn tempFromValue(cg: *CodeGen, ty: Type, value: MCValue) !Temp { |
| 28507 | return .{ .index = temp_index.toIndex() }; | 28662 | return .{ .index = temp_index.toIndex() }; |
| 28508 | } | 28663 | } |
| 28509 | | 28664 | |
| | 28665 | fn tempFromValue(cg: *CodeGen, value: Value) !Temp { |
| | 28666 | return cg.tempInit(value.typeOf(cg.pt.zcu), try cg.genTypedValue(value)); |
| | 28667 | } |
| | 28668 | |
| 28510 | fn tempFromOperand( | 28669 | fn tempFromOperand( |
| 28511 | cg: *CodeGen, | 28670 | cg: *CodeGen, |
| 28512 | inst: Air.Inst.Index, | 28671 | inst: Air.Inst.Index, |
| ... | @@ -28549,7 +28708,7 @@ fn tempFromOperand( | ... | @@ -28549,7 +28708,7 @@ fn tempFromOperand( |
| 28549 | else => break :init const_mcv, | 28708 | else => break :init const_mcv, |
| 28550 | } | 28709 | } |
| 28551 | }); | 28710 | }); |
| 28552 | return cg.tempFromValue(.fromInterned(ip.typeOf(val)), gop.value_ptr.short); | 28711 | return cg.tempInit(.fromInterned(ip.typeOf(val)), gop.value_ptr.short); |
| 28553 | } | 28712 | } |
| 28554 | | 28713 | |
| 28555 | const temp_index = cg.next_temp_index; | 28714 | const temp_index = cg.next_temp_index; |
| ... | @@ -29023,8 +29182,8 @@ const Select = struct { | ... | @@ -29023,8 +29182,8 @@ const Select = struct { |
| 29023 | return switch (spec.kind) { | 29182 | return switch (spec.kind) { |
| 29024 | .unused => null, | 29183 | .unused => null, |
| 29025 | .any => try cg.tempAlloc(spec.type), | 29184 | .any => try cg.tempAlloc(spec.type), |
| 29026 | .cc => |cc| try cg.tempFromValue(spec.type, .{ .eflags = cc }), | 29185 | .cc => |cc| try cg.tempInit(spec.type, .{ .eflags = cc }), |
| 29027 | .reg => |reg| try cg.tempFromValue(spec.type, .{ .register = reg }), | 29186 | .reg => |reg| try cg.tempInit(spec.type, .{ .register = reg }), |
| 29028 | .rc => |rc| try cg.tempAllocReg(spec.type, regSetForRegClass(rc)), | 29187 | .rc => |rc| try cg.tempAllocReg(spec.type, regSetForRegClass(rc)), |
| 29029 | .rc_mask => |rc_mask| try cg.tempAllocReg(spec.type, regSetForRegClass(rc_mask.rc)), | 29188 | .rc_mask => |rc_mask| try cg.tempAllocReg(spec.type, regSetForRegClass(rc_mask.rc)), |
| 29030 | .mem => try cg.tempAllocMem(spec.type), | 29189 | .mem => try cg.tempAllocMem(spec.type), |
| ... | @@ -29081,18 +29240,14 @@ const Select = struct { | ... | @@ -29081,18 +29240,14 @@ const Select = struct { |
| 29081 | break :res_scalar .{ scalar_int_ty, try pt.intValue_big(scalar_int_ty, big_int.toConst()) }; | 29240 | break :res_scalar .{ scalar_int_ty, try pt.intValue_big(scalar_int_ty, big_int.toConst()) }; |
| 29082 | }, | 29241 | }, |
| 29083 | }; | 29242 | }; |
| 29084 | const res_ty, const res_val: Value = if (vector_len) |len| res: { | 29243 | const res_val: Value = if (vector_len) |len| .fromInterned(try pt.intern(.{ .aggregate = .{ |
| 29085 | const vector_ty = try pt.vectorType(.{ | 29244 | .ty = (try pt.vectorType(.{ |
| 29086 | .len = len, | 29245 | .len = len, |
| 29087 | .child = res_scalar_ty.toIntern(), | 29246 | .child = res_scalar_ty.toIntern(), |
| 29088 | }); | 29247 | })).toIntern(), |
| 29089 | const vector_val = try pt.intern(.{ .aggregate = .{ | 29248 | .storage = .{ .repeated_elem = res_scalar_val.toIntern() }, |
| 29090 | .ty = vector_ty.toIntern(), | 29249 | } })) else res_scalar_val; |
| 29091 | .storage = .{ .repeated_elem = res_scalar_val.toIntern() }, | 29250 | return try cg.tempFromValue(res_val); |
| 29092 | } }); | | |
| 29093 | break :res .{ vector_ty, .fromInterned(vector_val) }; | | |
| 29094 | } else .{ res_scalar_ty, res_scalar_val }; | | |
| 29095 | return try cg.tempFromValue(res_ty, try cg.genTypedValue(res_val)); | | |
| 29096 | }, | 29251 | }, |
| 29097 | .ref => |ref| ref.deref(s), | 29252 | .ref => |ref| ref.deref(s), |
| 29098 | .ref_mask => |ref_mask| ref_mask.ref.deref(s), | 29253 | .ref_mask => |ref_mask| ref_mask.ref.deref(s), |