diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 392f9089a7..99e3ea3471 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -47,10 +47,11 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features .scalarize_div_float_optimized = use_old, .scalarize_div_trunc = use_old, .scalarize_div_trunc_optimized = use_old, - .scalarize_div_floor = use_old, + .scalarize_div_floor = true, .scalarize_div_floor_optimized = use_old, .scalarize_div_exact = use_old, .scalarize_div_exact_optimized = use_old, + .scalarize_mod = true, .scalarize_max = use_old, .scalarize_min = use_old, .scalarize_add_with_overflow = true, @@ -690,7 +691,7 @@ const InstTracking = struct { } tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long }); try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{}); - for (self.short.getRegs()) |reg| if (reg.class() == .x87) try cg.asmRegister(.{ .f_, .free }, reg); + for (self.short.getRegs()) |reg| if (reg.isClass(.x87)) try cg.asmRegister(.{ .f_, .free }, reg); } fn reuseFrame(self: *InstTracking) void { @@ -2468,7 +2469,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void { } fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { - @setEvalBranchQuota(28_600); + @setEvalBranchQuota(28_700); const pt = cg.pt; const zcu = pt.zcu; const ip = &zcu.intern_pool; @@ -35458,12 +35459,249 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }; try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg); }, - .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else fallback: { + .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else { const bin_op = air_datas[@intFromEnum(inst)].bin_op; - if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, air_tag); + const ty = cg.typeOf(bin_op.lhs); var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); var res: [1]Temp = undefined; - cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{ + (if (cg.intInfo(ty)) |int_info| err: switch (int_info.signedness) { + .signed => cg.select(&res, &.{ty}, &ops, comptime &.{ .{ + .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any }, + .patterns = &.{ + .{ .src = .{ .any, .any, .none } }, + }, + .dst_temps = .{ .{ .imm = 0 }, .unused }, + .each = .{ .once = &.{} }, + }, .{ + .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any }, + .patterns = &.{ + .{ .src = .{ .mem, .to_mut_gphi, .none } }, + .{ .src = .{ .to_gpr, .to_mut_gphi, .none } }, + }, + .dst_temps = .{ .{ .reg = .al }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ }, + .{ ._, .i_, .div, .src1b, ._, ._, ._ }, + .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ }, + .{ ._, ._, .cmp, .src1b, .sia(1, .src0, .add_smin), ._, ._ }, + .{ ._, ._, .adc, .dst0b, .si(-1), ._, ._ }, + } }, + }, .{ + .required_features = .{ .fast_imm16, null, null, null }, + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i16, .kind = .{ .reg = .dx } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ref = .src0 }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ }, + .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ }, + .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i16, .kind = .{ .reg = .dx } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ref = .src0 }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ }, + .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ }, + .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i32, .kind = .{ .reg = .edx } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ref = .src0 }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cdq, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1d, ._, ._, ._ }, + .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ }, + .{ ._, ._, .cmp, .src1d, .sia(1, .src0, .add_smin), ._, ._ }, + .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i64, .kind = .{ .reg = .rdx } }, + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ref = .src0 }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cqo, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1q, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .@"and", .src1q, .tmp1q, ._, ._ }, + .{ ._, ._, .xor, .src1q, .tmp0q, ._, ._ }, + .{ ._, ._c, .st, ._, ._, ._, ._ }, + .{ ._, ._, .sbb, .src1q, .tmp1q, ._, ._ }, + .{ ._, ._, .adc, .dst0q, .si(-1), ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any }, + .patterns = &.{ + .{ .src = .{ .mem, .mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .i128, .kind = .{ .param_gpr_pair = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } }, + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ }, + .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ }, + .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ }, + .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .call, .tmp2d, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0q0, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .mov, .tmp0q1, .tmp0q0, ._, ._ }, + .{ ._, ._, .@"and", .tmp0q1, .tmp1q, ._, ._ }, + .{ ._, ._, .xor, .tmp0q1, .dst0q1, ._, ._ }, + .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ }, + .{ ._, ._, .sbb, .tmp0q1, .tmp0q0, ._, ._ }, + .{ ._, ._, .sbb, .tmp3q, .tmp3q, ._, ._ }, + .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ }, + .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ }, + .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ }, + .{ ._, ._, .call, .tmp4d, ._, ._, ._ }, + .{ ._, ._c, .st, ._, ._, ._, ._ }, + .{ ._, ._, .sbb, .dst0q0, .tmp3q, ._, ._ }, + .{ ._, ._, .sbb, .dst0q1, .tmp3q, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ + .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, + .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, + .any, + }, + .patterns = &.{ + .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .i32, .kind = .{ .rc = .general_purpose } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } }, + .{ .kind = .{ .mem_of_type = .dst0 } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } }, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .mem, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ }, + .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ }, + .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ }, + .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ }, + .{ ._, ._, .mov, .tmp4d, .memad(.src0d, .add_size, -4), ._, ._ }, + .{ ._, ._, .xor, .tmp4d, .memad(.src1d, .add_size, -4), ._, ._ }, + .{ ._, ._, .call, .tmp5d, ._, ._, ._ }, + .{ ._, ._, .@"test", .tmp4d, .tmp4d, ._, ._ }, + .{ ._, ._ns, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .lea, .tmp0p, .mem(.tmp6), ._, ._ }, + .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ }, + .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ }, + .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ }, + .{ ._, ._, .call, .tmp7d, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ }, + .{ .@"1:", ._, .cmp, .memi(.tmp6q, .tmp0), .si(0), ._, ._ }, + .{ ._, ._e, .j, .@"3f", ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0p, .sa(.dst0, .sub_size_div_8), ._, ._ }, + .{ .@"2:", ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .si(-1), ._, ._ }, + .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, + .{ ._, ._nz, .j, .@"2b", ._, ._, ._ }, + .{ .@"3:", ._, .sub, .tmp0d, .si(8), ._, ._ }, + .{ ._, ._ae, .j, .@"1b", ._, ._, ._ }, + } }, + } }), + .unsigned => res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err, + } else cg.select(&res, &.{ty}, &ops, comptime &.{ .{ .required_features = .{ .f16c, null, null, null }, .src_constraints = .{ .{ .scalar_float = .{ .of = .word, .is = .word } }, @@ -36494,10 +36732,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, } }, - } }) catch |err| switch (err) { + } })) catch |err| switch (err) { error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ @tagName(air_tag), - cg.typeOf(bin_op.lhs).fmt(pt), + ty.fmt(pt), ops[0].tracking(cg), ops[1].tracking(cg), }), @@ -36510,6 +36748,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); var res: [1]Temp = undefined; cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{ + .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any }, + .patterns = &.{ + .{ .src = .{ .any, .any, .none } }, + }, + .dst_temps = .{ .{ .imm = 0 }, .unused }, + .each = .{ .once = &.{} }, + }, .{ .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any }, .patterns = &.{ .{ .src = .{ .mem, .mem, .none } }, @@ -36616,8 +36861,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any }, .patterns = &.{ .{ .src = .{ - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } }, - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } }, .none, } }, }, @@ -36635,7 +36880,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -36645,8 +36890,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any }, .patterns = &.{ .{ .src = .{ - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } }, - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } }, .none, } }, }, @@ -36664,7 +36909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -36681,10 +36926,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } }, .unused, .unused, @@ -36714,10 +36959,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } }, .unused, .unused, @@ -37078,12 +37323,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } }, - .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } }, + .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } }, .unused, .unused, .unused, @@ -37116,12 +37361,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } }, - .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } }, + .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } }, .unused, .unused, .unused, @@ -37154,10 +37399,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } }, .unused, .unused, @@ -37190,10 +37435,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } }, .unused, .unused, @@ -37987,12 +38232,498 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }; try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg); }, - .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else fallback: { + .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else { const bin_op = air_datas[@intFromEnum(inst)].bin_op; - if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, .mod); var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); var res: [1]Temp = undefined; cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{ + .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any }, + .patterns = &.{ + .{ .src = .{ .any, .any, .none } }, + }, + .dst_temps = .{ .{ .imm = 0 }, .unused }, + .each = .{ .once = &.{} }, + }, .{ + .required_features = .{ .cmov, null, null, null }, + .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any }, + .patterns = &.{ + .{ .src = .{ .mem, .to_mut_gphi, .none } }, + .{ .src = .{ .to_gpr, .to_mut_gphi, .none } }, + }, + .extra_temps = .{ + .{ .type = .i8, .kind = .{ .rc = .gphi } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .reg = .ah }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ }, + .{ ._, .i_, .div, .src1b, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ }, + .{ ._, ._, .add, .tmp0h, .src1b, ._, ._ }, + .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ }, + .{ ._, ._, .cmp, .src1b, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._a, .cmov, .dst0d, .tmp0d, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any }, + .patterns = &.{ + .{ .src = .{ .mem, .to_gphi, .none } }, + .{ .src = .{ .to_gpr, .to_gphi, .none } }, + }, + .extra_temps = .{ + .{ .type = .i8, .kind = .{ .rc = .gphi } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .reg = .ah }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ }, + .{ ._, .i_, .div, .src1b, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .tmp0b, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .tmp0b, .dst0h, ._, ._ }, + .{ ._, ._, .cmp, .tmp0b, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._na, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0h, .src1b, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any }, + .patterns = &.{ + .{ .src = .{ .mem, .mem, .none } }, + .{ .src = .{ .to_gpr, .mem, .none } }, + .{ .src = .{ .mem, .to_gpr, .none } }, + .{ .src = .{ .to_gpr, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .ah }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .movzx, .dst0d, .src0b, ._, ._ }, + .{ ._, ._, .div, .src1b, ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .cmov, .fast_imm16, null, null }, + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .dx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .add, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ }, + } }, + }, .{ + .required_features = .{ .cmov, null, null, null }, + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .dx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .add, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ }, + } }, + }, .{ + .required_features = .{ .fast_imm16, null, null, null }, + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .dx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src0w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._na, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0d, .src1d, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .dx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cwd, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1w, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._na, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0d, .src1d, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } }, + .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .dx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ }, + .{ ._, ._, .div, .src1w, ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .cmov, null, null, null }, + .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .edx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cdq, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1d, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .add, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src1d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .edx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cdq, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1d, ._, ._, ._ }, + .{ ._, ._, .mov, .src0d, .src1d, ._, ._ }, + .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ }, + .{ ._, ._, .cmp, .src0d, .sa(.src0, .add_smin), ._, ._ }, + .{ ._, ._na, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0d, .src1d, ._, ._ }, + } }, + }, .{ + .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } }, + .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .edx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ }, + .{ ._, ._, .div, .src1d, ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", .cmov, null, null }, + .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .reg = .rdx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cqo, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1q, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .src0q, .dst0q, ._, ._ }, + .{ ._, ._, .add, .src0q, .src1q, ._, ._ }, + .{ ._, ._, .@"and", .src1q, .tmp0q, ._, ._ }, + .{ ._, ._, .xor, .src1q, .dst0q, ._, ._ }, + .{ ._, ._, .cmp, .src1q, .tmp0q, ._, ._ }, + .{ ._, ._a, .cmov, .dst0q, .src0q, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } }, + }, + .extra_temps = .{ + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .reg = .rdx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .cqo, ._, ._, ._, ._ }, + .{ ._, .i_, .div, .src1q, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .src0q, .src1q, ._, ._ }, + .{ ._, ._, .@"and", .src0q, .tmp0q, ._, ._ }, + .{ ._, ._, .xor, .src0q, .dst0q, ._, ._ }, + .{ ._, ._, .cmp, .src0q, .tmp0q, ._, ._ }, + .{ ._, ._na, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0q, .src1q, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } }, + .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } }, + }, + .dst_temps = .{ .{ .reg = .rdx }, .unused }, + .clobbers = .{ .eflags = true }, + .each = .{ .once = &.{ + .{ ._, ._, .xor, .dst0q, .dst0q, ._, ._ }, + .{ ._, ._, .div, .src1q, ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", .cmov, null, null }, + .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } }, + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .call, .tmp1d, ._, ._, ._ }, + .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ }, + .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ }, + .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ }, + .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, + .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ }, + .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ }, + .{ ._, ._nae, .cmov, .src0q0, .tmp2q, ._, ._ }, + .{ ._, ._ae, .cmov, .tmp2q, .mem(.src1q), ._, ._ }, + .{ ._, ._, .add, .dst0q0, .tmp2q, ._, ._ }, + .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any }, + .patterns = &.{ + .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .call, .tmp1d, ._, ._, ._ }, + .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ }, + .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ }, + .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ }, + .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ }, + .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ }, + .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ }, + .{ ._, ._nae, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .add, .dst0q0, .mem(.src1q), ._, ._ }, + .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any }, + .patterns = &.{ + .{ .src = .{ + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } }, + .none, + } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ + .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, + .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, + .any, + }, + .patterns = &.{ + .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } }, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .mem, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ }, + .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ }, + .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ }, + .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ }, + .{ ._, ._, .mov, .tmp4q, .memad(.src1q, .add_size, -8), ._, ._ }, + .{ ._, ._, .call, .tmp5d, ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0d, .sia(-3, .dst0, .add_size_div_8), ._, ._ }, + .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ }, + .{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ }, + .{ ._, ._, .@"and", .tmp2q, .tmp1q, ._, ._ }, + .{ ._, ._, .xor, .tmp2q, .memad(.dst0q, .add_size, -8), ._, ._ }, + .{ ._, ._, .cmp, .memad(.dst0q, .add_size, -16), .si(1), ._, ._ }, + .{ .@"0:", ._, .mov, .tmp3q, .memsi(.dst0q, .@"8", .tmp0), ._, ._ }, + .{ ._, ._, .sbb, .tmp3q, .si(0), ._, ._ }, + .{ ._, ._c, .de, .tmp0d, ._, ._, ._ }, + .{ ._, ._ns, .j, .@"0b", ._, ._, ._ }, + .{ ._, ._, .sbb, .tmp2q, .tmp1q, ._, ._ }, + .{ ._, ._nae, .j, .@"0f", ._, ._, ._ }, + .{ ._, ._, .mov, .tmp0p, .sa(.src1, .sub_size_div_8), ._, ._ }, + .{ ._, ._, .@"test", .tmp4q, .tmp4q, ._, ._ }, + .{ ._, ._ns, .j, .@"2f", ._, ._, ._ }, + .{ .@"1:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ }, + .{ ._, ._, .sbb, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ }, + .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, + .{ ._, ._nz, .j, .@"1b", ._, ._, ._ }, + .{ ._, ._mp, .j, .@"0f", ._, ._, ._ }, + .{ .@"2:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ }, + .{ ._, ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ }, + .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, + .{ ._, ._nz, .j, .@"2b", ._, ._, ._ }, + } }, + }, .{ + .required_features = .{ .@"64bit", null, null, null }, + .src_constraints = .{ + .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, + .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } }, + .any, + }, + .patterns = &.{ + .{ .src = .{ .to_mem, .to_mem, .none } }, + }, + .call_frame = .{ .alignment = .@"16" }, + .extra_temps = .{ + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, + .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } }, + .unused, + .unused, + .unused, + .unused, + .unused, + .unused, + }, + .dst_temps = .{ .mem, .unused }, + .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, + .each = .{ .once = &.{ + .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ }, + .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ }, + .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ }, + .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ }, + .{ ._, ._, .call, .tmp4d, ._, ._, ._ }, + } }, + }, .{ .required_features = .{ .f16c, .fast_imm16, null, null }, .src_constraints = .{ .{ .scalar_float = .{ .of = .word, .is = .word } }, @@ -160281,9 +161012,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { inline .memcpy, .memmove => |symbol| comptime &.{.{ .patterns = &.{ .{ .src = .{ - .{ .to_param_gpr = .{ .cc = .ccc, .index = 0 } }, - .{ .to_param_gpr = .{ .cc = .ccc, .index = 1 } }, - .{ .to_param_gpr = .{ .cc = .ccc, .index = 2 } }, + .{ .to_param_gpr = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr = .{ .cc = .ccc, .at = 1 } }, + .{ .to_param_gpr = .{ .cc = .ccc, .at = 2 } }, } }, }, .call_frame = .{ .alignment = .@"16" }, @@ -160333,7 +161064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .avx, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"32" }, .extra_temps = .{ @@ -160359,7 +161090,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .sse, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ @@ -160384,7 +161115,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }, .{ .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"8" }, .extra_temps = .{ @@ -160424,7 +161155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .avx, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"32" }, .extra_temps = .{ @@ -160440,7 +161171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .zigcc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -160449,7 +161180,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .sse, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ @@ -160465,7 +161196,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .zigcc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -160473,7 +161204,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }, .{ .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"8" }, .extra_temps = .{ @@ -160489,7 +161220,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .zigcc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -160621,7 +161352,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .avx, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"32" }, .extra_temps = .{ @@ -160647,7 +161378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .required_features = .{ .sse, null, null, null }, .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ @@ -160672,7 +161403,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { }, .{ .src_constraints = .{ .{ .int = .gpr }, .any, .any }, .patterns = &.{ - .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } }, + .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } }, }, .call_frame = .{ .alignment = .@"8" }, .extra_temps = .{ @@ -162921,7 +163652,7 @@ fn getValueIfFree(self: *CodeGen, value: MCValue, inst: ?Air.Inst.Index) void { fn freeReg(self: *CodeGen, reg: Register) !void { self.register_manager.freeReg(reg); - if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg); + if (reg.isClass(.x87)) try self.asmRegister(.{ .f_, .free }, reg); } fn freeValue(self: *CodeGen, value: MCValue) !void { @@ -163840,7 +164571,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { else => src_int_info.bits, }; - const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else src_abi_size > 8) and + const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else src_abi_size > 8) and dst_int_info.bits <= src_storage_bits and std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable == std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and @@ -163921,7 +164652,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; defer if (src_lock) |lock| self.register_manager.unlockReg(lock); - const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.class() == self.regClassForType(dst_ty) and + const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.isClass(self.regClassForType(dst_ty)) and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else if (dst_abi_size <= 8) @@ -176332,7 +177063,11 @@ fn genSetReg( ), }, .ip, .cr, .dr => unreachable, - }, + } else if ((dst_reg.class() == .gphi) != (src_reg.class() == .gphi)) try self.asmRegisterRegister( + .{ ._, .mov }, + dst_reg.to8(), + src_reg.to8(), + ), inline .register_pair, .register_triple, .register_quadruple, @@ -176452,7 +177187,7 @@ fn genSetReg( }); }, .register_mask => |src_reg_mask| { - assert(src_reg_mask.reg.class() == .sse); + assert(src_reg_mask.reg.isClass(.sse)); const has_avx = self.hasFeature(.avx); const bits_reg = switch (dst_reg.class()) { .general_purpose => dst_reg, @@ -177055,7 +177790,7 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { defer if (src_lock) |lock| self.register_manager.unlockReg(lock); const dst_mcv = if (src_mcv != .register_mask and - (if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else true) and + (if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else true) and dst_rc.supersetOf(src_rc) and dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and dst_ty.abiAlignment(zcu).order(src_ty.abiAlignment(zcu)).compare(.lte) and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { @@ -179909,7 +180644,7 @@ fn airReduce(self: *CodeGen, inst: Air.Inst.Index) !void { const operand_reg = registerAlias(operand_reg: { if (operand_mcv.isRegister()) { const operand_reg = operand_mcv.getReg().?; - if (operand_reg.class() == .general_purpose) break :operand_reg operand_reg; + if (operand_reg.isClass(.general_purpose)) break :operand_reg operand_reg; } break :operand_reg try self.copyToTmpRegister(operand_ty, operand_mcv); }, abi_size); @@ -180779,12 +181514,12 @@ fn resolveCallingConventionValues( ret_tracking_i += 1; } }, - .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .sse), + .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.sse)), .x87 => { ret_tracking[ret_tracking_i] = .init(.{ .register = abi.getCAbiX87ReturnRegs(cc)[0] }); ret_tracking_i += 1; }, - .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .x87), + .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.x87)), .complex_x87 => { ret_tracking[ret_tracking_i] = .init(.{ .register_pair = abi.getCAbiX87ReturnRegs(cc)[0..2].* }); ret_tracking_i += 1; @@ -180871,7 +181606,7 @@ fn resolveCallingConventionValues( arg_mcv_i += 1; } }, - .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse), + .sseup => assert(arg_mcv[arg_mcv_i - 1].register.isClass(.sse)), .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (cc) { .x86_64_sysv => switch (class) { .x87, .x87up, .complex_x87, .memory => break, @@ -181864,8 +182599,8 @@ const Temp = struct { const val = temp.tracking(cg).short; if (!mut or temp.isMut(cg)) switch (val) { else => {}, - .register => |reg| if (reg.class() == rc) return false, - .register_offset => |reg_off| if (reg_off.reg.class() == rc and reg_off.off == 0) return false, + .register => |reg| if (reg.isClass(rc)) return false, + .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(rc)) return false, }; const ty = temp.typeOf(cg); const new_temp_index = cg.next_temp_index; @@ -185888,6 +186623,21 @@ const Temp = struct { var ops: [2]Temp = .{ lhs.*, rhs.* }; var res: [1]Temp = undefined; try cg.select(&res, &.{lhs.typeOf(cg)}, &ops, comptime &.{ .{ + .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any }, + .patterns = &.{ + .{ .src = .{ .any, .any, .none } }, + }, + .dst_temps = .{ .{ .imm = 0 }, .unused }, + .each = .{ .once = &.{} }, + }, .{ + .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .{ .exact_unsigned_int = 1 }, .any }, + .patterns = &.{ + .{ .src = .{ .mut_mem, .any, .none } }, + .{ .src = .{ .to_mut_gpr, .any, .none } }, + }, + .dst_temps = .{ .{ .ref = .src0 }, .unused }, + .each = .{ .once = &.{} }, + }, .{ .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any }, .patterns = &.{ .{ .src = .{ .mem, .mem, .none } }, @@ -186072,8 +186822,8 @@ const Temp = struct { .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any }, .patterns = &.{ .{ .src = .{ - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } }, - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } }, .none, } }, }, @@ -186091,7 +186841,7 @@ const Temp = struct { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -186101,8 +186851,8 @@ const Temp = struct { .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any }, .patterns = &.{ .{ .src = .{ - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } }, - .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, + .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } }, .none, } }, }, @@ -186120,7 +186870,7 @@ const Temp = struct { .unused, .unused, }, - .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused }, + .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused }, .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, .each = .{ .once = &.{ .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, @@ -186137,10 +186887,10 @@ const Temp = struct { }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } }, .unused, .unused, @@ -186170,10 +186920,10 @@ const Temp = struct { }, .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } }, .unused, .unused, @@ -186534,12 +187284,12 @@ const Temp = struct { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } }, - .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } }, + .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } }, .unused, .unused, .unused, @@ -186572,12 +187322,12 @@ const Temp = struct { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivti3" } } }, - .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } }, + .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } }, .unused, .unused, .unused, @@ -186610,10 +187360,10 @@ const Temp = struct { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } }, .unused, .unused, @@ -186646,10 +187396,10 @@ const Temp = struct { .call_frame = .{ .alignment = .@"16" }, .extra_temps = .{ .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } }, - .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } }, + .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } }, .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } }, .unused, .unused, @@ -187117,8 +187867,7 @@ const Select = struct { } fn lowerReg(s: *const Select, reg: Register) Register { - if (reg.class() != .x87) return reg; - return @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top)); + return if (reg.isClass(.x87)) @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top)) else reg; } const Case = struct { @@ -187505,6 +188254,8 @@ const Select = struct { to_gpr, mut_gpr, to_mut_gpr, + to_gphi, + to_mut_gphi, x87, to_x87, mut_x87, @@ -187581,84 +188332,84 @@ const Select = struct { .mut_mem => temp.isMut(cg) and temp.tracking(cg).short.isMemory(), .to_reg, .to_reg_pair, .to_param_gpr, .to_param_gpr_pair, .to_ret_gpr, .to_ret_gpr_pair => true, .gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .general_purpose, - .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0, + .register => |reg| reg.isClass(.general_purpose), + .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0, else => false, }, .immut_gpr => !temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .general_purpose, - .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0, + .register => |reg| reg.isClass(.general_purpose), + .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0, else => false, }, .mut_gpr => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .general_purpose, - .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0, + .register => |reg| reg.isClass(.general_purpose), + .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0, else => false, }, - .to_gpr, .to_mut_gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8, + .to_gpr, .to_mut_gpr, .to_gphi, .to_mut_gphi => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8, .x87 => switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .x87, - .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0, + .register => |reg| reg.isClass(.x87), + .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0, else => false, }, .mut_x87 => temp.isMut(cg) and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .x87, - .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0, + .register => |reg| reg.isClass(.x87), + .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0, else => false, }, .to_x87, .to_mut_x87 => true, .mmx => switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .mmx, - .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0, + .register => |reg| reg.isClass(.mmx), + .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0, else => false, }, .mut_mmx => temp.isMut(cg) and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .mmx, - .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0, + .register => |reg| reg.isClass(.mmx), + .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0, else => false, }, .to_mmx, .to_mut_mmx => true, .mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .mmx, - .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0, + .register => |reg| reg.isClass(.mmx), + .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0, else => false, }, .mut_mm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .mmx, - .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0, + .register => |reg| reg.isClass(.mmx), + .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0, else => false, }, .to_mm, .to_mut_mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8, .sse => switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .mut_sse => temp.isMut(cg) and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .to_sse, .to_mut_sse => true, .xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .mut_xmm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .to_xmm, .to_mut_xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16, .ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .mut_ymm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) { - .register => |reg| reg.class() == .sse, - .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0, + .register => |reg| reg.isClass(.sse), + .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0, else => false, }, .to_ymm, .to_mut_ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32, @@ -187684,12 +188435,14 @@ const Select = struct { .mut_mem, .to_mut_mem => try temp.toBase(true, cg), .to_reg => |reg| try temp.toReg(reg, cg), .to_reg_pair => |regs| try temp.toRegPair(regs, cg), - .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index], cg), - .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, cg), - .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index], cg), - .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, cg), + .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at], cg), + .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*, cg), + .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at], cg), + .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*, cg), .gpr, .immut_gpr, .to_gpr => try temp.toRegClass(false, .general_purpose, cg), .mut_gpr, .to_mut_gpr => try temp.toRegClass(true, .general_purpose, cg), + .to_gphi => try temp.toRegClass(false, .gphi, cg), + .to_mut_gphi => try temp.toRegClass(true, .gphi, cg), .x87, .to_x87 => try temp.toRegClass(false, .x87, cg), .mut_x87, .to_mut_x87 => try temp.toRegClass(true, .x87, cg), .mmx, .to_mmx, .mm, .to_mm => try temp.toRegClass(false, .mmx, cg), @@ -187761,7 +188514,7 @@ const Select = struct { const CallConvRegSpec = struct { cc: Case.CallConv, - index: u2, + at: u2, fn tag(spec: CallConvRegSpec, cg: *const CodeGen) std.builtin.CallingConvention.Tag { return switch (spec.cc) { @@ -187778,10 +188531,10 @@ const Select = struct { else => return reg_locks, .reg => |reg| .{ reg, .none }, .reg_pair => |regs| regs, - .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..1].* ++ .{.none}, - .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, - .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..1].* ++ .{.none}, - .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, + .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..1].* ++ .{.none}, + .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*, + .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..1].* ++ .{.none}, + .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*, }; for (regs, ®_locks) |reg, *reg_lock| { if (reg == .none) continue; @@ -187791,13 +188544,6 @@ const Select = struct { } return reg_locks; } - - fn finish(kind: Kind, temp: Temp, cg: *CodeGen) void { - switch (kind) { - else => {}, - inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg), - } - } }; fn create(spec: TempSpec, s: *const Select) InnerError!struct { Temp, bool } { @@ -187822,24 +188568,24 @@ const Select = struct { .reg => |reg| .{ try cg.tempInit(spec.type, .{ .register = reg }), true }, .reg_pair => |regs| .{ try cg.tempInit(spec.type, .{ .register_pair = regs }), true }, .param_gpr => |param_spec| .{ try cg.tempInit(spec.type, .{ - .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index], + .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at], }), true }, .param_gpr_pair => |param_spec| .{ try cg.tempInit(spec.type, .{ - .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, + .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*, }), true }, .ret_gpr => |ret_spec| .{ try cg.tempInit(spec.type, .{ - .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index], + .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at], }), true }, .ret_gpr_pair => |ret_spec| .{ try cg.tempInit(spec.type, .{ - .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, + .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*, }), true }, .rc => |rc| .{ try cg.tempAllocReg(spec.type, regSetForRegClass(rc)), true }, .rc_pair => |rc| .{ try cg.tempAllocRegPair(spec.type, regSetForRegClass(rc)), true }, .mut_rc => |ref_rc| { const temp = ref_rc.ref.tempOf(s); if (temp.isMut(cg)) switch (temp.tracking(cg).short) { - .register => |reg| if (reg.class() == ref_rc.rc) return .{ temp, false }, - .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc.rc) return .{ temp, false }, + .register => |reg| if (reg.isClass(ref_rc.rc)) return .{ temp, false }, + .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc.rc)) return .{ temp, false }, else => {}, }; return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc.rc)), true }; @@ -187849,8 +188595,8 @@ const Select = struct { .mut_rc_mask => |ref_rc_mask| { const temp = ref_rc_mask.ref.tempOf(s); if (temp.isMut(cg)) switch (temp.tracking(cg).short) { - .register => |reg| if (reg.class() == ref_rc_mask.rc) return .{ temp, false }, - .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc_mask.rc) return .{ temp, false }, + .register => |reg| if (reg.isClass(ref_rc_mask.rc)) return .{ temp, false }, + .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc_mask.rc)) return .{ temp, false }, else => {}, }; return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc_mask.rc)), true }; @@ -188228,6 +188974,14 @@ const Select = struct { } }), true }, }; } + + fn finish(spec: TempSpec, temp: *Temp, cg: *CodeGen) InnerError!void { + switch (spec.kind) { + else => {}, + inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg), + } + cg.temp_type[@intFromEnum(temp.unwrap(cg).temp)] = spec.type; + } }; const Instruction = struct { @@ -188255,8 +189009,7 @@ const Select = struct { const Tag = enum(u3) { none, - backward_label, - forward_label, + label, ref, simm, uimm, @@ -188626,16 +189379,16 @@ const Select = struct { const @"_": Select.Operand = .{ .flags = .{ .tag = .none } }; - const @"0b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp0, .size = .none } } }; - const @"0f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp0, .size = .none } } }; - const @"1b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp1, .size = .none } } }; - const @"1f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp1, .size = .none } } }; - const @"2b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp2, .size = .none } } }; - const @"2f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp2, .size = .none } } }; - const @"3b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp3, .size = .none } } }; - const @"3f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp3, .size = .none } } }; - const @"4b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp4, .size = .none } } }; - const @"4f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp4, .size = .none } } }; + const @"0b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 0) }; + const @"0f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 0) }; + const @"1b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 1) }; + const @"1f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 1) }; + const @"2b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 2) }; + const @"2f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 2) }; + const @"3b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 3) }; + const @"3f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 3) }; + const @"4b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 4) }; + const @"4f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 4) }; const tmp0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0l } }; const tmp0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0h } }; @@ -188648,6 +189401,8 @@ const Select = struct { const tmp0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0t } }; const tmp0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0x } }; const tmp0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0y } }; + const tmp0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 1 }; + const tmp0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 2 }; const tmp1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1l } }; const tmp1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1h } }; @@ -188660,6 +189415,8 @@ const Select = struct { const tmp1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1t } }; const tmp1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1x } }; const tmp1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1y } }; + const tmp1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 1 }; + const tmp1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 2 }; const tmp2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2l } }; const tmp2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2h } }; @@ -188672,6 +189429,8 @@ const Select = struct { const tmp2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2t } }; const tmp2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2x } }; const tmp2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2y } }; + const tmp2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 1 }; + const tmp2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 2 }; const tmp3l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3l } }; const tmp3h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3h } }; @@ -188684,6 +189443,8 @@ const Select = struct { const tmp3t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3t } }; const tmp3x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3x } }; const tmp3y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3y } }; + const tmp3q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 1 }; + const tmp3q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 2 }; const tmp4l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4l } }; const tmp4h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4h } }; @@ -188696,6 +189457,8 @@ const Select = struct { const tmp4t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4t } }; const tmp4x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4x } }; const tmp4y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4y } }; + const tmp4q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 1 }; + const tmp4q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 2 }; const tmp5l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5l } }; const tmp5h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5h } }; @@ -188708,6 +189471,8 @@ const Select = struct { const tmp5t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5t } }; const tmp5x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5x } }; const tmp5y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5y } }; + const tmp5q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 1 }; + const tmp5q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 2 }; const tmp6l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6l } }; const tmp6h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6h } }; @@ -188720,6 +189485,8 @@ const Select = struct { const tmp6t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6t } }; const tmp6x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6x } }; const tmp6y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6y } }; + const tmp6q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 1 }; + const tmp6q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 2 }; const tmp7l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7l } }; const tmp7h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7h } }; @@ -188732,6 +189499,8 @@ const Select = struct { const tmp7t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7t } }; const tmp7x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7x } }; const tmp7y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7y } }; + const tmp7q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 1 }; + const tmp7q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 2 }; const tmp8l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8l } }; const tmp8h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8h } }; @@ -188744,6 +189513,8 @@ const Select = struct { const tmp8t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8t } }; const tmp8x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8x } }; const tmp8y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8y } }; + const tmp8q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 1 }; + const tmp8q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 2 }; const tmp9l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9l } }; const tmp9h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9h } }; @@ -188756,6 +189527,8 @@ const Select = struct { const tmp9t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9t } }; const tmp9x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9x } }; const tmp9y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9y } }; + const tmp9q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 1 }; + const tmp9q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 2 }; const tmp10l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10l } }; const tmp10h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10h } }; @@ -188768,6 +189541,8 @@ const Select = struct { const tmp10t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10t } }; const tmp10x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10x } }; const tmp10y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10y } }; + const tmp10q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 1 }; + const tmp10q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 2 }; const dst0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0l } }; const dst0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0h } }; @@ -188780,6 +189555,8 @@ const Select = struct { const dst0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0t } }; const dst0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0x } }; const dst0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0y } }; + const dst0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 1 }; + const dst0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 2 }; const dst1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1l } }; const dst1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1h } }; @@ -188792,6 +189569,8 @@ const Select = struct { const dst1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1t } }; const dst1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1x } }; const dst1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1y } }; + const dst1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 1 }; + const dst1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 2 }; const src0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0l } }; const src0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0h } }; @@ -188804,6 +189583,8 @@ const Select = struct { const src0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0t } }; const src0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0x } }; const src0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0y } }; + const src0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 1 }; + const src0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 2 }; const src1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1l } }; const src1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1h } }; @@ -188816,6 +189597,8 @@ const Select = struct { const src1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1t } }; const src1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1x } }; const src1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1y } }; + const src1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 1 }; + const src1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 2 }; const src2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2l } }; const src2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2h } }; @@ -188828,6 +189611,8 @@ const Select = struct { const src2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2t } }; const src2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2x } }; const src2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2y } }; + const src2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 1 }; + const src2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 2 }; fn si(imm: i32) Select.Operand { return .{ .flags = .{ .tag = .simm }, .imm = imm }; @@ -189207,24 +189992,41 @@ const Select = struct { fn lower(op: Select.Operand, s: *Select) InnerError!CodeGen.Operand { return switch (op.flags.tag) { .none => .none, - .backward_label => .{ .inst = s.labels[@intFromEnum(op.flags.base.ref)].backward.? }, - .forward_label => for (&s.labels[@intFromEnum(op.flags.base.ref)].forward) |*label| { + .label => if (op.imm < 0) + .{ .inst = s.labels[@intCast(~op.imm)].backward.? } + else for (&s.labels[@intCast(op.imm)].forward) |*label| { if (label.*) |_| continue; label.* = @intCast(s.cg.mir_instructions.len); break .{ .inst = undefined }; } else unreachable, - .ref => switch (op.flags.base.ref.valueOf(s)) { - .immediate => |imm| .{ .imm = switch (op.flags.base.size) { - .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))), - .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))), - .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))), - .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm), - else => unreachable, - } }, - else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) }, - .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) }, - .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) }, - .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) }, + .ref => switch (op.imm) { + else => unreachable, + 0 => switch (op.flags.base.ref.valueOf(s)) { + .none, .unreach, .dead, .undef => unreachable, + .immediate => |imm| .{ .imm = switch (op.flags.base.size) { + .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))), + .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))), + .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))), + .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm), + else => unreachable, + } }, + .eflags => unreachable, + .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) }, + .register_pair, .register_triple, .register_quadruple, .register_offset, .register_overflow => unreachable, + .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) }, + else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) }, + .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) }, + .load_direct, .lea_direct, .load_got, .lea_got, .lea_frame, .elementwise_args, .reserved_frame, .air_ref => unreachable, + }, + 1...2 => |imm| switch (op.flags.base.ref.valueOf(s)) { + inline .register_pair, .register_triple, .register_quadruple => |regs| .{ + .reg = s.lowerReg(regs[@intCast(imm - 1)].toSize(op.flags.base.size, s.cg.target)), + }, + else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ + .size = op.flags.base.size, + .disp = @as(i32, @intCast(@divExact(op.flags.base.size.bitSize(s.cg.target), 8))) * (imm - 1), + }) }, + }, }, .simm => .{ .imm = .s(op.adjustedImm(i32, s)) }, .uimm => .{ .imm = .u(@bitCast(op.adjustedImm(i64, s))) }, @@ -189392,11 +190194,8 @@ fn select( }, } } - for (case.dst_temps[0..dst_temps.len], dst_temps, dst_tys) |tmp_kind, dst_temp, dst_ty| { - tmp_kind.finish(dst_temp, cg); - cg.temp_type[@intFromEnum(dst_temp.unwrap(cg).temp)] = dst_ty; - } for (tmp_owned, s_tmp_temps) |owned, temp| if (owned) try temp.die(cg); + for (dst_tys, case.dst_temps[0..dst_temps.len], dst_temps) |dst_ty, dst_kind, *dst_temp| try Select.TempSpec.finish(.{ .type = dst_ty, .kind = dst_kind }, dst_temp, cg); return; } } diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index caa16bfec4..3dfd557220 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -575,22 +575,22 @@ const RegisterBitSet = RegisterManager.RegisterBitSet; pub const RegisterClass = struct { pub const gp: RegisterBitSet = blk: { var set = RegisterBitSet.initEmpty(); - for (allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index); + for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.general_purpose)) set.set(index); break :blk set; }; pub const gphi: RegisterBitSet = blk: { var set = RegisterBitSet.initEmpty(); - for (allocatable_regs, 0..) |reg, index| if (reg.hasHi8()) set.set(index); + for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.gphi)) set.set(index); break :blk set; }; pub const x87: RegisterBitSet = blk: { var set = RegisterBitSet.initEmpty(); - for (allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index); + for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.x87)) set.set(index); break :blk set; }; pub const sse: RegisterBitSet = blk: { var set = RegisterBitSet.initEmpty(); - for (allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index); + for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.sse)) set.set(index); break :blk set; }; }; diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index c5ccc40bab..062a57981c 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -429,6 +429,16 @@ pub const Register = enum(u8) { }; } + pub inline fn isClass(reg: Register, rc: Class) bool { + switch (rc) { + else => return reg.class() == rc, + .gphi => { + const reg_id = reg.id(); + return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id(); + }, + } + } + pub fn id(reg: Register) u7 { const base = switch (@intFromEnum(reg)) { // zig fmt: off @@ -615,22 +625,17 @@ pub const Register = enum(u8) { } pub fn toHi8(reg: Register) Register { - assert(reg.hasHi8()); + assert(reg.isClass(.gphi)); return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ah)); } - pub fn hasHi8(reg: Register) bool { - const reg_id = reg.id(); - return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id(); - } - pub fn to80(reg: Register) Register { - assert(reg.class() == .x87); + assert(reg.isClass(.x87)); return reg; } fn sseBase(reg: Register) u8 { - assert(reg.class() == .sse); + assert(reg.isClass(.sse)); return switch (@intFromEnum(reg)) { @intFromEnum(Register.zmm0)...@intFromEnum(Register.zmm31) => @intFromEnum(Register.zmm0), @intFromEnum(Register.ymm0)...@intFromEnum(Register.ymm31) => @intFromEnum(Register.ymm0), @@ -694,11 +699,13 @@ test "Register enc - different classes" { } test "Register classes" { - try expect(Register.r11.class() == .general_purpose); - try expect(Register.ymm11.class() == .sse); - try expect(Register.mm3.class() == .mmx); - try expect(Register.st3.class() == .x87); - try expect(Register.fs.class() == .segment); + try expect(Register.r11.isClass(.general_purpose)); + try expect(Register.rdx.isClass(.gphi)); + try expect(!Register.dil.isClass(.gphi)); + try expect(Register.ymm11.isClass(.sse)); + try expect(Register.mm3.isClass(.mmx)); + try expect(Register.st3.isClass(.x87)); + try expect(Register.fs.isClass(.segment)); } pub const FrameIndex = enum(u32) { diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 4042c528ae..9cacd955d7 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -111,7 +111,7 @@ pub const Instruction = struct { }; pub fn initMoffs(reg: Register, offset: u64) Memory { - assert(reg.class() == .segment); + assert(reg.isClass(.segment)); return .{ .moffs = .{ .seg = reg, .offset = offset } }; } @@ -139,7 +139,7 @@ pub const Instruction = struct { .rip => false, .sib => |s| switch (s.base) { .none, .frame, .table, .reloc, .rip_inst => false, - .reg => |reg| reg.class() == .segment, + .reg => |reg| reg.isClass(.segment), }, }; } @@ -199,7 +199,7 @@ pub const Instruction = struct { pub fn isSegmentRegister(op: Operand) bool { return switch (op) { .none => unreachable, - .reg => |reg| reg.class() == .segment, + .reg => |reg| reg.isClass(.segment), .mem => |mem| mem.isSegmentRegister(), .imm => unreachable, .bytes => unreachable, @@ -776,7 +776,7 @@ pub const LegacyPrefixes = packed struct { padding: u5 = 0, pub fn setSegmentOverride(self: *LegacyPrefixes, reg: Register) void { - assert(reg.class() == .segment); + assert(reg.isClass(.segment)); switch (reg) { .cs => self.prefix_2e = true, .ss => self.prefix_36 = true, @@ -2457,7 +2457,7 @@ const Assembler = struct { .general_purpose, .segment => { const tok = try as.expect(.string); const base = registerFromString(as.source(tok)) orelse return error.InvalidMemoryOperand; - if (base.class() != cond) return error.InvalidMemoryOperand; + if (!base.isClass(cond)) return error.InvalidMemoryOperand; res.base = base; }, .rip => { @@ -2498,7 +2498,7 @@ const Assembler = struct { error.Overflow => { if (is_neg) return err; if (res.base) |base| { - if (base.class() != .segment) return err; + if (!base.isClass(.segment)) return err; } const offset = try std.fmt.parseInt(u64, as.source(tok), 0); res.offset = offset; diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 8eec0a4df9..232ba11eea 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1893,13 +1893,13 @@ test "float divide by zero" { test "partially-runtime integer vector division would be illegal if vector elements were reordered" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; var lhs: @Vector(2, i8) = .{ -128, 5 }; const rhs: @Vector(2, i8) = .{ 1, -1 }; diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index 9bd37dd4e5..a8b531bcca 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -559,12 +559,12 @@ test "vector comparison operators" { test "vector division operators" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; const S = struct { fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void { diff --git a/test/behavior/x86_64/binary.zig b/test/behavior/x86_64/binary.zig index 7fd0c9575d..ee34840b9e 100644 --- a/test/behavior/x86_64/binary.zig +++ b/test/behavior/x86_64/binary.zig @@ -5181,6 +5181,8 @@ inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@divFloor( } test divFloor { const test_div_floor = binary(divFloor, .{ .compare = .approx_int }); + try test_div_floor.testInts(); + try test_div_floor.testIntVectors(); try test_div_floor.testFloats(); try test_div_floor.testFloatVectors(); } @@ -5198,7 +5200,7 @@ test rem { inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs)) { // workaround llvm backend bugs - if (@inComptime()) { + if (@inComptime() and @typeInfo(Scalar(Type)) == .float) { const scalarMod = struct { fn scalarMod(scalar_lhs: Scalar(Type), scalar_rhs: Scalar(Type)) Scalar(Type) { const scalar_rem = @rem(scalar_lhs, scalar_rhs); @@ -5218,6 +5220,8 @@ inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs)) } test mod { const test_mod = binary(mod, .{}); + try test_mod.testInts(); + try test_mod.testIntVectors(); try test_mod.testFloats(); try test_mod.testFloatVectors(); }